Ferrari's Fernando Alonso was second and championship leader Nico Rosberg, who started on pole position for Mercedes, finished fourth and saw his lead over Hamilton cut from 14 points to 11.
Instead of Rosberg and Mercedes running away with the race, the race ran away from Rosberg with his team beaten for only the second time in 11 grands prix.
Ricciardo, a revelation in his first year at Red Bull, emptied his lungs in sheer elation after he took the chequered flag 5.2 seconds ahead of the Spaniard for his second win of the season and of his career.
"It feels as good as the first win, it really does," beamed the Australian, who took his first win in Canada, after a rollercoaster of a race with two safety car periods and plenty of incident.
"The safety car at first played to our advantage but the second one didn't really help us, but we got there in the end and I had to do the overtaking at the end which was fun."
All of the top four had led over the course of a race that started after a brief downpour, was interrupted by two big crashes, continued with the ever-present threat of rain and finished on a knife-edge.
Ricciardo, who had led earlier in the race and was on fresher tyres, swept past Hamilton three laps from the end and overtook a determined Alonso to regain the lead for good with two laps to go.
"We took a gamble to try to get the victory and we got very close," said Alonso of his second podium finish of the season.
"We need some crazy races to get a podium and we took our chances today."
Behind them, Rosberg - who had also made three stops to Alonso and Hamilton's two - was closing in remorselessly and was all over the back of his team mate's car as they started the final lap.
Hamilton hung on, after earlier disregarding calls from the team to let Rosberg pass because the German still had one more pitstop to make, to seize a podium finish that had looked improbable on Saturday.
"I was just pushing as hard as I could to see if I could get as high as I could," said Hamilton, who had won for the last two years in Hungary and finished third in Germany last weekend after starting 20th.
The Briton had to start from the pitlane - and behind Danish rookie Kevin Magnussen whose McLaren was also moved off the grid - after his car caught fire in qualifying before he had completed a lap.
He spun at the second corner, skimming the wall without damage, and was 21 seconds down on Rosberg after the first lap with a mountain to climb.
By lap seven Hamilton was up to 14th and events played into his hands when the safety car was deployed after Sweden's Marcus Ericsson crashed his Caterham at turn three.
While the top four decided not to pit, in what proved out to be a mistake that turned the race on its head, Hamilton and others did. Ricciardo then took the lead when they came in a lap later.
Frenchman Romain Grosjean kept the safety car out for four more laps when he crashed his Lotus on lap 11 and there was a further interruption on lap 23 when Force India's Mexican Sergio Perez speared into the wall on the pit straight.