The Ecuadorian pipped Denmark's Jakob Fuglsang (Astana-Premier Tech) to the line in a sprint finish on the summit at Leukerbad.
Fuglsang had attacked with 18 kilometres to go but Carapaz flew away from the main group to catch him three kilometres out.
The Dane looked like taking the win until Carapaz overtook him on the outside in the dying metres.
After time bonuses, Carapaz had the overall lead by 26 seconds over second-placed Fuglsang.
Julian Alaphilippe (Deceuninck-QuickStep) dropped from third to fourth after copping a 20-second penalty for taking an illegal feed, pushing Maximilian Schachmann into the top three.
"I'm really happy. It's something we've been working on all week," said Carapaz in the aftermath.
"We knew it was a special day. We wanted to think about the general classification, of course, and the possibility of winning a stage was there. I did both, so I'm happy.
"We knew there was a lot of people interested in the general classification. It was a launchpad for us. We were thinking about the general classification. I made my perfect attack and that was it.
"We're here. We came thinking about preparing for the tour. Of course, we wanted to try and win this.
"We know the main objective is the Tour but if we can win this it's good."