The FDJ.fr sprinter recovered from a puncture on the penultimate lap - and avoided numerous spills in the peloton - to win his first stage of a Grand Tour ahead of Italy's Giacomo Nizzolo (Trek Factory Racing) and Dutchman Tom Veelers (Giant-Shimano).
Australia's Michael Matthews (Orica-GreenEdge) retained the race lead on a day double stage winner Marcel Kittel of Giant-Shimano withdrew due to fever.
Torrential rain in the start town of Giovinazzo enforced an unofficial go-slow in the peloton at the start of the short and flat 112km stage - the first after the race's opening three-day foray in Ireland. Although the rain soon cleared, the riders entered the Adriatic port of Bari for the first of eight circuits at a sluggish pace.
After numerous negotiations between riders and the race commissaire it was decided that times for the overall classification would be taken with one of the 8km laps remaining - and time bonuses would be scrapped.
The pace increased accordingly, with Bouhanni picking up a flat tyre at an inopportune moment at the start of the penultimate lap. With two FDJ team-mates pacing him back, the 23-year-old just managed to rejoin the pack ahead of the final lap.
With the overall times for GC now taken, numerous riders - including the pink jersey Matthews - eased up just as the heavens opened.
The showers caused the exact same chaos that the riders had initially feared - and two tight bends inside the last 3km saw numerous bodies slip to the deck at top speed.
The Giant-Shimano team of the departed Kittel looked to have benefited from the chaotic scenes: entering the final 2km they had four riders in a six-man group off the front.
But Bouhanni was one of a handful of riders who managed to bridge the gap in the closing stages, the Frenchman surging past Veelers on the final slight rise to the line and taking Italian youngster Nizzolo with him.
Italians Roberto Ferrari (Lampre-Merida) and Elia Viviani (Cannondale) completed the top five, while Slovenian Luka Mezgec - the man expected to replace Kittel as Giant's main sprinter - had to settle for eighth place after suffering a problem with his chain in the final few hundred metres.
"I thought that I would never get back onto the peloton," Bouhanni said after the biggest win of his career. "But the team did very well to get me back on. In the final straight I had to give everything and fortunately I won."
For his part, Matthews was happy to complete the stage unscathed and defended his team's decision to enforce a slower, neutralised pace during the majority of the stage.
"From the start it was really slippery," he said. "Straight away we had a chat in the bunch and decided to neutralise the race. It's a long tour and we all need to stay safe out there.
"It's totally different to Ireland [which] is a country where it always rains and the roads are used to the changing conditions. Here in south Italy the roads are not used to so much rain."
MARCEL KITTEL WITHDRAWAL: Moments before the stage of the stage the German sprinter pulled out of the race due to a fever. The 26-year-old from Giant-Shimano won stages two and three and had a comfortable lead in the red jersey points standings.
NEUTRALISATION: With the bad weather following the riders from Dublin, the peloton enforced a go-slow from the start of the stage in Giovinazzo. Orica-GreenEdge kept a steady pace on the front of the pack, marshalling matters. Numerous riders - including Italian veterans Luca Paolini (Katusha) and Paolo Tiralongo (Astana) - spoke to the race commissaire during the stage. The rain eased up but the roads in Bari were still deemed too dangerous. After a few circuits of the city centre it was decided that the final times would be taken after the penultimate lap and that the bonus seconds over the finish would be scrapped.
BIG WINNER OF THE DAY: Nacer Bouhanni finally opened his Grand Tour account with a superb ride, recovering from a puncture and then not giving up when it seemed very much in the bag for Giant-Shimano. The FDJ.fr sprinter was rewarded with both the stage win and the red points jersey.
BIG LOSERS OF THE DAY: Bari and its inhabitants. The southern port city had not hosted the Giro since 1990 and was rewarded with truly farcical scenes.
KEY MOMENT: Bouhanni being paced back onto the back of the peloton following his puncture was key - but the numerous spills inside the last few kilometres no doubt disrupted the pace of the pack somewhat, helping the Frenchman close the gap. Add to that Mezgec's issues with his chain, and you could say that Bouhanni - after a gross piece of misfortune - had fortune smiling down upon him.
TALKING POINT: Were the riders right to enforce a neutralised go-slow? The crashes on the final lap suggests that perhaps they had a case, after all. Prior to that, the heavy rain seemed to stop well before the peloton arrived for the first of eight circuits in Bari and the seemingly dry roads could hardly have been described as treacherous. Had the pace been faster from the start, you could even say that the late downpour would have come too late to have been a factor.
COMING UP: The 203km fifth stage includes the first Cat.3 climb of the race ahead of back-to-back Cat.4 climbs, including the final ramp to the finish in Viggiano. The 5% gradient is probably enough to shell out most of the sprinters - although the pink jersey Michael Matthews may fancy his chances.
1. Nacer Bouhanni (France / FDJ.fr) 2:22:06"
2. Giacomo Nizzolo (Italy / Trek) ST
3. Tom Veelers (Netherlands / Giant)
4. Roberto Ferrari (Italy / Lampre)
5. Elia Viviani (Italy / Cannondale)
6. Matteo Montaguti (Italy / AG2R)
7. Kenny Dehaes (Belgium / Lotto)
8. Luka Mezgec (Slovenia / Giant)
9. Bert De Backer (Belgium / Giant)
10. Francesco Chicchi (Italy / Neri Sottoli)
11. Mauro Finetto (Italy / Neri Sottoli)
12. Leonardo Duque (Colombia / Colombia)
13. Marco Frapporti (Italy / Androni Giocattoli)
14. Eugenio Alafaci (Italy / Trek)
15. Johan Le Bon (France / FDJ.fr)
16. Diego Rosa (Italy / Androni Giocattoli)
17. Fabian Wegmann (Germany / Garmin)
18. Oscar Gatto (Italy / Cannondale)
19. Alessandro Petacchi (Italy / Omega Pharma - Quick-Step)
20. Jeffry Romero (Colombia / Colombia)
21. Yonathan Monsalve (Venezuela / Neri Sottoli)
22. Albert Timmer (Netherlands / Giant)
23. Dylan van Baarle (Netherlands / Garmin)
24. Tobias Ludvigsson (Sweden / Giant)
25. Fumiyuki Beppu (Japan / Trek)
26. Sebastien Chavanel (France / FDJ.fr)
27. Daniel Oss (Italy / BMC Racing)
28. Georg Preidler (Austria / Giant)
29. Nicola Boem (Italy / Bardiani Valvole)
30. Bernhard Eisel (Austria / Team Sky)
- Sports & Recreation
- Michael Matthews
- Marcel Kittel