The 17-year-old Guinea-Bissau-born attacker picked up a Luis Suarez cross to fire home four minutes from time to become the youngest player to score in the Champions League.
Barcelona were already through to the knockout stages as Group F winners and they left six-time Ballon d’Or winner Lionel Messi at home.
But Serie A leaders Inter needed a win over the La Liga leaders or to match Borussia Dortmund’s result at home to Slavia Prague to qualify on their superior head-to-head record.
Instead the Germans made it through to the knockout rounds with a 2-1 win to finish three points ahead of third-placed Inter, who go into the Europa League.
“Seeing replays of Fati’s goal hurt,” said Inter coach Antonio Conte.
“It’s a goal that cut our legs from under us and killed us from all points of view.
“We lacked that pinch of cynicism and precision to finish off. I have little to reproach my players, they have given everything.”
– ‘Born scorer’ –
Debutant Carles Perez had put the Spaniards ahead after 23 minutes at the San Siro, but Romelu Lukaku drilled in a equaliser just before the break to keep the hosts in the tie.
Inter’s forward pair of Lukaku and Lautaro Martinez had three goals ruled offside between them, two for the Argentine who has already scored five times in the competition this year.
“There was a lot of newness because we also changed our system,” said Barcelona coach Ernesto Valverde.
“We had a few problems at the beginning because they put us under pressure, but little by little we managed to come out better.
“The scorers were young players, even very young for Ansu, who is a born scorer.
“It’s a matter of pride that it’s a player who is from our team. We want to win the Champions League, like the others.”
Suarez had started on the bench with Antoine Griezmann and Perez leading the Spaniards attack.
The Spaniards weathered an early Inter blitz on goal buoyed by the 72,000 crowd.
Danilo D’Ambrosio blasted over in front of goal after just five minutes, with Lukaku having a goal ruled offside minutes later.
But Perez made the breakthrough with Arturo Vidal setting up the 21-year-old to beat Samir Handanovic in the Inter goal.
Martinez sent Lukaku through for the equaliser and the Belgium forward’s effort took a slight deflection to beat Neto.
But the Italians lost momentum after the hour mark with their midfield depleted with injuries to Stefano Sensi, Nicolo Barella, Alexis Sanchez and Roberto Gagliardini.
Conte sent on Matteo Politano and Sebastiano Esposito for the final push as news filtered through that Dortmund were leading Slavia 2-1, and Inter needed to win.
Martinez had the ball in the net on 80 minutes, but again it was ruled out for Lukaku’s offside position.
Finally Fati broke through to seal the win late for Barcelona and deny Inter a return to the knockout stages for the first time since the 2011-2012 season.