Lewis Hamilton pulled off a tactical masterstroke and benefited from a Red Bull pit-stop blunder to win the Monaco Grand Prix and get his championship challenge firmly back on track.
Pole-sitter Daniel Ricciardo crossed the line of a fascinating weather-hit race in second while Force India's Sergio Perez completed the podium places.
Championship leader Nico Rosberg struggled in the early wet conditions — at one stage he was instructed by Mercedes to move over for a much-faster Hamilton — and finished seventh, 93 seconds behind his team-mate, after Nico Hulkenberg pipped him on the line.
It allowed Hamilton, who ended an eight-race losing streak here, to dramatically slash the gap to Rosberg to 24 points in his quest to become the only British driver to win four championships.
The drama-fuelled race started under a safety car following a deluge of rain at the principality, and while the entire field pitted for intermediate tyres, Hamilton took what would be the race-winning decision to stay out on the extreme wet option.
It enabled the world champion to take control at a track where overtaking is virtually impossible, before he eventually stopped for dry rubber on lap 31.
Ricciardo pitted one lap later, but his pit crew were inexplicably not ready for him, and he emerged behind the British driver.
It was a blunder, which the Red Bull team later blamed on a “miscommunication”, and one which would ultimately cost Ricciardo his first victory in nearly two years.
The Australian, who had started on pole, attempted to pass Hamilton after the world champion made a mistake at the chicane, but the Briton afforded him little room.
“What the f***? was that?” asked a furious Ricciardo as he waved his hand at Hamilton. The incident was subsequently investigated by the stewards who took no further action.
Ricciardo kept Hamilton honest over the remaining laps, but was unable to find a way past. The gap as they crossed the line would be more than seven seconds.
“I am kind of lost for words,” said Hamilton. “I prayed for a day like this and it came through. I feel truly blessed.”
While Hamilton claimed his first victory at Monte Carlo since 2008, it marked a day to forget for the winner here for the last three years.
Rosberg was incredibly slow in the early wet conditions, losing nearly 10 seconds to Ricciardo in the opening four laps after the safety car pitted at the end of lap seven.
He was told to move out of Hamilton’s way by his Mercedes team and eventually slipped to sixth in the order. That is where he seem poised to finish, but to cap a terrible afternoon at his adopted home, he was passed in the closing stages by Force India’s Hulkenberg to finish the race in seventh.
Britain's Jolyon Palmer was the first driver to crash out after losing his Renault in spectacular fashion on the pit straight while Max Verstappen, the 18-year-old Dutchman, who became the sport's youngest-ever winner last time out in Spain, also failed to reach the end after a collision with the barriers. It was his third shunt of a weekend which brought him firmly back down to earth after his Barcelona heroics.
Sebastian Vettel was fourth for Ferrari with Jenson Button completing a double-points finish for McLaren on their 50th anniversary after he crossed the line in ninth.
A distraught Ricciardo, who looked certain to win in Spain a fortnight ago until Red Bull pitted him one more time than his team-mate Verstappen, cut a disconsolate figure.
“The race shouldn’t have been as exciting as it was to be honest,” he said. “Two weekends in a row now I have been screwed. It sucks. It hurts.”
Asked about the pit-stop blunder, he added: “I have no idea. I was called into the box. I didn’t make the call. They should have been ready.”