Neymar’s low finish and a sublime chip by Alexis Sanchez sent Real to a second defeat in four league games.
Brazil forward Neymar beat Diego Lopez with a right-foot finish before Sanchez settled the game with a 20-yard chip.
Real’s Karim Benzema hit the bar before fellow substitute Jese Rodriguez scored a consolation in stoppage time after a strong run by Cristiano Ronaldo.
Gareth Bale started but has still to complete a full 90 minutes for Real in La Liga after being substituted on the hour.
The 24-year-old Wales international, a world record £85m signing from Tottenham last month, rarely threatened in his forward role and was booked for a foul on Barca defender Gerard Pique, one of seven cautions in a fiercely contested game.
Instead it was Barca’s Neymar, who cost £36m less than Bale, who took centre stage. His third La Liga goal in 10 appearances settled a tense game that failed to live up to its billing as the most anticipated fixture in the world.
Real, now six points behind Barca 10 games into the season, did not come alive until after the interval.
By then the hosts had established the lead, Neymar’s composed finish rounding off a free-flowing move involving Sergio Busquets and Andres Iniesta.
Lionel Messi should have doubled the lead two minutes later but fired wide after sloppy play in the Real defence.
It said much about Real’s performance that their first chance of the half did not arrive until the 44th minute, Valdes denying Germany midfielder Sami Khedira from close range with his knee.
Valdes again came to his side’s rescue after Iniesta lost possession and Luka Modric carved out an opening for Ronaldo.
But after Benzema’s terrific strike rattled the Barca bar in the 72nd minute and Ronaldo had a penalty appeal waved away after a challenge by Javier Mascherano, Real were undone by a moment of pure brilliance by substitute Sanchez.
The Chile international beat Lopez, who was standing off his line, from 20 yards with a perfect chip 12 minutes from time.
Real did find the net in stoppage time, Rodriguez firing home after being set up by Ronaldo.
But that failed to take the gloss off Barca’s victory, their first over Real in four attempts in La Liga.