Pedri González scored from long range to give Barcelona the lead in the 28th minute at La Cartuja Stadium on Saturday.
Kylian Mbappé came off the bench at halftime and scored from a free kick for Real Madrid in the 70th. Midfielder Aurélien Tchouaméni headed Madrid in front in the 77th.
But Ferran Torres leveled in the 84th and forced extra time.
Jules Koundé then pounced on a pass by Brahim Díaz and slotted a shot into the low corner of Thibaut Courtois' net for the 116th-minute winner.
Barcelona will carry this momentum into Wednesday's start of their Champions League semi-final against Inter Milan. They also lead La Liga by four points over Madrid.
Barcelona have beaten Madrid in all three of their clasicos this season. They routed Madrid 5-2 in the Spanish Super Cup final in January after winning 4-0 at Madrid in the league in October.
"This was such a physically demanding game, but we showed that we are a great team that never gives up," said Torres, who filled in perfectly for the injured Robert Lewandowski.
Madrid defender Antonio Rudiger was shown a red card by the referee in the final minute of extra time.
The loss to their fierce rivals is another blow to Madrid after they were knocked out of the Champions League quarter-finals by Arsenal.
This could have been their last final with Carlo Ancelotti in charge. The Italian coach said he will decide his future this summer amid speculation he is bound to take over Brazil.