Richard Carapaz was on the brink of winning the Giro d'Italia after he retained the overall leader's pink jersey in Saturday's penultimate stage in the Dolomites.

The Ecuadorian comfortably held off two-time champion Vincenzo Nibali in the 194-km ride from Feltre as the 20th stage was won by Spaniard Pello Bilbao.

It was a chaotic ride throughout, with Colombian Miguel Angel Lopez, who holds the white jersey for the best Under-25 rider, lashing out at a fan after tangling with him in the final few kilometres.

The Astana rider could face an exclusion from the race, which ends in Verona with a 17-km individual time trial on Sunday.

Lopez was one of the attackers of the day, but the top guns held firm, with the exception of Slovenian Primoz Roglic, who was dropped in the final climb up to Monte Avena.

As a result, the Jumbo-Visma rider slipped from third to fourth overall to the benefit of Spain's Mikel Landa, Carapaz's lieutenant at Movistar.

Overall, Carapaz leads Nibali by 1:54 and Landa by 2:53, with Roglic 3:06 off the pace.

Sensing Roglic's weakness and trying to make the most of his last chance of unsettling Carapaz, Nibali, one of two active riders with titles in all three grand tours, gave everything in the last four kilometres.

But the duo of Carapaz and Landa proved too hard to shake off, while Bilbao sprinted to victory on the day. 

Ireland's Eddie Dunbar was in the breakway and finished 1:59 behind winner Bilbao in 19th place for Team Ineos. He's 21st in the general classification.