With leading goalscorer Haaland deemed fit enough only for the bench after missing the previous two City games through injury, Argentinean forward Julian Alvarez fired the home side into a 17th-minute lead.
The champions thought they had quickly doubled their lead through John Stones but Rodri was offside in the build-up, and Fulham capitalised on that reprieve, going straight down the other end and winning a 26th-minute penalty.
City defender Joao Cancelo was given a straight red card for bundling Harry Wilson to the floor, with former Manchester United midfielder Andreas Pereira making no mistake from the spot as Fulham went into the interval level.
City continued to dominate even with a numerical disadvantage. Haaland was brought on and quickly thought he had restored his side’s lead after glancing a header home, but VAR stepped in to rule the Norwegian to be offside.
It seemed City had done all they could until Kevin De Bruyne was brought down and Haaland converted the penalty to send the Etihad Stadium into delirium in the 95th minute, as the champions moved one point clear of Arsenal at the top of the standings. Fulham stayed eighth.
Additional reporting from Reuters