Playmaker Şahin, 22, helped steer Dortmund to this season's Bundesliga title and will join the La Liga giants as they seek to end Barcelona's grip on the domestic title and chase a 10th Champions League triumph.
While the clubs did not disclose how much Real agreed to pay, his contract with Dortmund included a clause that allowed him to leave if there was an offer of 10 million euros (8.8 million pounds) or more from outside Germany.
Şahin, who has missed his team's last three matches through injury and is expected to be out for six weeks, said he was very proud to make the move to the Spanish capital.
"The decision was hard to take. I am Borussia and will remain Borussia," he told reporters.
German-born Şahin is both the youngest ever Bundesliga player, making his debut in August 2005 aged 16 years and 355 days, and the youngest scorer, netting against Nuremberg three months into his top-flight career.
He made his Turkey debut in 2005 in a 2-1 win over Germany in Istanbul, becoming the youngest player to score for his country when he made it 2-0.
"I will miss the Bundesliga and my homeland. I would like to thank everyone who has accompanied me on this journey until now," added Şahin, who has been at the club since the age of 12.
He played 135 matches for the German side and scored 13 goals, including six this season as Dortmund claimed their first Bundesliga title since 2001-02.
Spanish media reported on Monday that Real were also looking to buy Bayern Munich midfielder Hamit Altintop, another Turkish international.
Şahin's arrival and the possible purchase of Altintop could mean that Real midfielders Fernando Gago, Sergio Canales and Pedro Leon, little used this season, will move on.