Mario Balotelli replied for City who had lots of possession but failed to make it count.
Cavani put the Serie A side ahead from a corner in the 18th minute and side-footed the winner early in the second half in front of a passionate San Paolo crowd.
The win put Napoli up into second place, a point ahead of City, with one game remaining and both clubs still in the hunt for a place in the knockout phase.
Balotelli replied for City in the 33rd minute in a generally subdued performance by his standards and also had a late effort stopped by Morgan De Sanctis.
Napoli looked dangerous with every attack. Marek Hamsik headed straight at Joe Hart after Ezequiel Lavezzi’s cross picked him out, then Lavezzi himself fired wide after a one-two with Cavani.
The Uruguayan, struggling to repeat last season’s prolific scoring this term, gave Napoli the lead when he flicked on a corner and the ball deflected off two City players into the net.
Almost immediately, Cavani struck the side-netting following another quick break to the right but the Napoli storm then blew itself out and City levelled.
Edin Dzeko crossed, Salvatore Aronica sent a dreadful clearance straight to David Silva in the penalty area and, although his angled shot was saved by De Sanctis, Balotelli was on hand to snap up the rebound.
City appeared to be on top but it was Napoli who regained the lead four minutes after the restart.
Lavezzi worked an opening for Andrea Dossena on the left and he pulled the ball back into the middle for Cavani to sidefoot home first time.
Despite home advantage, the Italians fell back into defence and tried to frustrate City.
However, Lavezzi and Cavani were always dangerous on the break and the Argentine forced a superb save from Hart after slipping his marker, before Hamsik hit the post.