The Slovakian rider beat Nibali of Astana and Katusha's Joaquim Rodríguez in a three-man sprint at the end of the 209km stage that began and ended in Porto Sant’Elpidio.
Team Sky's Froome was in the third group on the road and finished 50 seconds behind defending champion Nibali.
It means the Italian goes into Tuesday's final time trial, that begins and ends in San Benedetto del Tronto, 34 seconds ahead of the Briton on GC. Rodriguez is three seconds further back in third with Alberto Contador fourth at 48 seconds.
A relentlessly lumpy course with more than 20 distinct hills, albeit with only three categorised climbs, created an action packed day in wet eastern Italy.
Nibali was part of a 16-man escape group that also featured Fabian Cancellara (RadioShack), Rinaldo Nocentini, Matteo Montaguti (Ag2r), Lars Boom (Blanco), Giovanni Visconti and Benat Intxausti (Movistar), Egoi Martínez (Euskaltel-Euskadi), Angel Vicioso (Katusha), Paul Voss (NetApp), Daryl Impey and Stuart O'Grady (Orica-GreenEdge), Tom Dumoulin and Matthieu Sprick (Argos), Mirko Selvaggi (Vacansoleil) and Mauro Finetto (Cannondale).
Their lead stood at 4:35 with 95km to go but had been reduced to less than 2:30 inside the final 50km and the escape group split on the second ascent of the 365m climb at Sant’Elpidio al Mare, which averaged 19.8% with ramps of 27%.
The peloton were within striking distance on the third ascent of the climb, which came with 15km remaining, and there was an attack by Nibali on the descent. He was joined by Sagan and Rodríguez and they came to the line together where the Cannondale rider cruised to his second stage win of the race.
Mauro Santambrogio (Vini Fantini-Selle Italia) led Samuel Sánchez (Euskaltel), Chris Horner (RadioShack-Leopard) and Contador over the line 44 seconds back with Froome's group a further six seconds behind.