The Australian cyclist was part of a large 18-man break for most of the 169-kilometre stage from Strathmore, Alta., to Drumheller, until a smaller group of six emerged in front that went all the way to the finish line.
Dennis, who finished in three hours 55 minutes 31 seconds, took first place in a photo finish in front of Brent Bookwalter, with Damiano Caruso in third.
Dennis has an 18-second lead over Bookwalter, and a 30-second lead over Caruso going into Saturday's fourth stage.
Peter Sagan, who led since the opening prologue, dropped to the 19th place, 16:35 behind.
The Best Canadian jersey also exchanged hands. Ryan Anderson Spruce Grove, Alta., part of the winning break, jumped to seventh place in the overall classification.
Victoria's Ryder Hesjedal, the 2012 Giro d'Italia winner, finished well out of contention 16:48 back in 90th.