diff --git a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri
index bec391fdcbc82b8a475afe8c02f179fc51aa2028..cf7e36ba832018116fb84ffffc173b3219af46a6 100644
--- a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri
+++ b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri
@@ -7,13 +7,15 @@ SUPPORT_QT_S60 = $$(QTCREATOR_WITH_S60)
         $$PWD/s60manager.cpp \
         $$PWD/winscwtoolchain.cpp \
         $$PWD/gccetoolchain.cpp \
-        $$PWD/s60emulatorrunconfiguration.cpp
+        $$PWD/s60emulatorrunconfiguration.cpp \
+        $$PWD/s60devicerunconfiguration.cpp
     HEADERS += $$PWD/s60devices.h \
         $$PWD/s60devicespreferencepane.h \
         $$PWD/s60manager.h \
         $$PWD/winscwtoolchain.h \
         $$PWD/gccetoolchain.h \
-        $$PWD/s60emulatorrunconfiguration.h
+        $$PWD/s60emulatorrunconfiguration.h \
+        $$PWD/s60devicerunconfiguration.h
     FORMS += $$PWD/s60devicespreferencepane.ui
     OTHER_FILES += $$PWD/qt-s60-todo.txt
 }
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..54e0fcba66a082b746ed2bb908f15b4f31324c0b
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
@@ -0,0 +1,305 @@
+#include "s60devicerunconfiguration.h"
+
+#include "qt4project.h"
+#include "qtversionmanager.h"
+#include "profilereader.h"
+#include "s60manager.h"
+#include "s60devices.h"
+
+#include <coreplugin/icore.h>
+#include <coreplugin/messagemanager.h>
+#include <utils/qtcassert.h>
+#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/project.h>
+
+using namespace ProjectExplorer;
+using namespace Qt4ProjectManager::Internal;
+
+// ======== S60DeviceRunConfiguration
+S60DeviceRunConfiguration::S60DeviceRunConfiguration(Project *project, const QString &proFilePath)
+    : RunConfiguration(project),
+    m_proFilePath(proFilePath),
+    m_cachedTargetInformationValid(false)
+{
+    if (!m_proFilePath.isEmpty())
+        setName(tr("%1 on Device").arg(QFileInfo(m_proFilePath).completeBaseName()));
+    else
+        setName(tr("QtS60DeviceRunConfiguration"));
+
+    connect(project, SIGNAL(activeBuildConfigurationChanged()),
+            this, SLOT(invalidateCachedTargetInformation()));
+}
+
+S60DeviceRunConfiguration::~S60DeviceRunConfiguration()
+{
+}
+
+QString S60DeviceRunConfiguration::type() const
+{
+    return "Qt4ProjectManager.DeviceRunConfiguration";
+}
+
+bool S60DeviceRunConfiguration::isEnabled() const
+{
+    Qt4Project *pro = qobject_cast<Qt4Project*>(project());
+    QTC_ASSERT(pro, return false);
+    ToolChain::ToolChainType type = pro->toolChainType(pro->activeBuildConfiguration());
+    return type == ToolChain::GCCE; //TODO || type == ToolChain::ARMV5
+}
+
+QWidget *S60DeviceRunConfiguration::configurationWidget()
+{
+    return new S60DeviceRunConfigurationWidget(this);
+}
+
+void S60DeviceRunConfiguration::save(PersistentSettingsWriter &writer) const
+{
+    const QDir projectDir = QFileInfo(project()->file()->fileName()).absoluteDir();
+    writer.saveValue("ProFile", projectDir.relativeFilePath(m_proFilePath));
+    RunConfiguration::save(writer);
+}
+
+void S60DeviceRunConfiguration::restore(const PersistentSettingsReader &reader)
+{
+    RunConfiguration::restore(reader);
+    const QDir projectDir = QFileInfo(project()->file()->fileName()).absoluteDir();
+    m_proFilePath = projectDir.filePath(reader.restoreValue("ProFile").toString());
+}
+
+QString S60DeviceRunConfiguration::executable() const
+{
+    const_cast<S60DeviceRunConfiguration *>(this)->updateTarget();
+    return m_executable;
+}
+
+void S60DeviceRunConfiguration::updateTarget()
+{
+    if (m_cachedTargetInformationValid)
+        return;
+    Qt4Project *pro = static_cast<Qt4Project *>(project());
+    Qt4PriFileNode * priFileNode = static_cast<Qt4Project *>(project())->rootProjectNode()->findProFileFor(m_proFilePath);
+    if (!priFileNode) {
+        m_executable = QString::null;
+        m_cachedTargetInformationValid = true;
+        emit targetInformationChanged();
+        return;
+    }
+    QtVersion *qtVersion = pro->qtVersion(pro->activeBuildConfiguration());
+    ProFileReader *reader = priFileNode->createProFileReader();
+    reader->setCumulative(false);
+    reader->setQtVersion(qtVersion);
+
+    // Find out what flags we pass on to qmake, this code is duplicated in the qmake step
+    QtVersion::QmakeBuildConfig defaultBuildConfiguration = qtVersion->defaultBuildConfig();
+    QtVersion::QmakeBuildConfig projectBuildConfiguration = QtVersion::QmakeBuildConfig(pro->qmakeStep()->value(pro->activeBuildConfiguration(), "buildConfiguration").toInt());
+    QStringList addedUserConfigArguments;
+    QStringList removedUserConfigArguments;
+    if ((defaultBuildConfiguration & QtVersion::BuildAll) && !(projectBuildConfiguration & QtVersion::BuildAll))
+        removedUserConfigArguments << "debug_and_release";
+    if (!(defaultBuildConfiguration & QtVersion::BuildAll) && (projectBuildConfiguration & QtVersion::BuildAll))
+        addedUserConfigArguments << "debug_and_release";
+    if ((defaultBuildConfiguration & QtVersion::DebugBuild) && !(projectBuildConfiguration & QtVersion::DebugBuild))
+        addedUserConfigArguments << "release";
+    if (!(defaultBuildConfiguration & QtVersion::DebugBuild) && (projectBuildConfiguration & QtVersion::DebugBuild))
+        addedUserConfigArguments << "debug";
+
+    reader->setUserConfigCmdArgs(addedUserConfigArguments, removedUserConfigArguments);
+
+    if (!reader->readProFile(m_proFilePath)) {
+        delete reader;
+        Core::ICore::instance()->messageManager()->printToOutputPane(tr("Could not parse %1. The QtS60 Device run configuration %2 can not be started.").arg(m_proFilePath).arg(name()));
+        return;
+    }
+
+    QString baseDir = S60Manager::instance()->devices()->deviceForId(
+            S60Manager::instance()->deviceIdFromDetectionSource(qtVersion->autodetectionSource())).epocRoot;
+    QString qmakeBuildConfig = "urel";
+    if (projectBuildConfiguration & QtVersion::DebugBuild)
+        qmakeBuildConfig = "udeb";
+    baseDir += "/epoc32/release/winscw/" + qmakeBuildConfig;
+
+    m_executable = QDir::toNativeSeparators(
+            QDir::cleanPath(baseDir + QLatin1Char('/') + reader->value("TARGET")));
+    m_executable += QLatin1String(".exe");
+
+    delete reader;
+    m_cachedTargetInformationValid = true;
+    emit targetInformationChanged();
+}
+
+void S60DeviceRunConfiguration::invalidateCachedTargetInformation()
+{
+    m_cachedTargetInformationValid = false;
+    emit targetInformationChanged();
+}
+
+// ======== S60DeviceRunConfigurationWidget
+
+S60DeviceRunConfigurationWidget::S60DeviceRunConfigurationWidget(S60DeviceRunConfiguration *runConfiguration,
+                                                                     QWidget *parent)
+    : QWidget(parent),
+    m_runConfiguration(runConfiguration)
+{
+    QFormLayout *toplayout = new QFormLayout();
+    toplayout->setMargin(0);
+    setLayout(toplayout);
+
+    QLabel *nameLabel = new QLabel(tr("Name:"));
+    m_nameLineEdit = new QLineEdit(m_runConfiguration->name());
+    nameLabel->setBuddy(m_nameLineEdit);
+    toplayout->addRow(nameLabel, m_nameLineEdit);
+
+    m_executableLabel = new QLabel(m_runConfiguration->executable());
+    toplayout->addRow(tr("Executable:"), m_executableLabel);
+
+    connect(m_nameLineEdit, SIGNAL(textEdited(QString)),
+        this, SLOT(nameEdited(QString)));
+    connect(m_runConfiguration, SIGNAL(targetInformationChanged()),
+            this, SLOT(updateTargetInformation()));
+}
+
+void S60DeviceRunConfigurationWidget::nameEdited(const QString &text)
+{
+    m_runConfiguration->setName(text);
+}
+
+void S60DeviceRunConfigurationWidget::updateTargetInformation()
+{
+    m_executableLabel->setText(m_runConfiguration->executable());
+}
+
+// ======== S60DeviceRunConfigurationFactory
+
+S60DeviceRunConfigurationFactory::S60DeviceRunConfigurationFactory(QObject *parent)
+    : IRunConfigurationFactory(parent)
+{
+}
+
+S60DeviceRunConfigurationFactory::~S60DeviceRunConfigurationFactory()
+{
+}
+
+bool S60DeviceRunConfigurationFactory::canRestore(const QString &type) const
+{
+    return type == "Qt4ProjectManager.DeviceRunConfiguration";
+}
+
+QStringList S60DeviceRunConfigurationFactory::availableCreationTypes(Project *pro) const
+{
+    Qt4Project *qt4project = qobject_cast<Qt4Project *>(pro);
+    if (qt4project) {
+        QStringList applicationProFiles;
+        QList<Qt4ProFileNode *> list = qt4project->applicationProFiles();
+        foreach (Qt4ProFileNode * node, list) {
+            applicationProFiles.append("QtS60DeviceRunConfiguration." + node->path());
+        }
+        return applicationProFiles;
+    } else {
+        return QStringList();
+    }
+}
+
+QString S60DeviceRunConfigurationFactory::displayNameForType(const QString &type) const
+{
+    QString fileName = type.mid(QString("QtS60DeviceRunConfiguration.").size());
+    return tr("%1 on Device").arg(QFileInfo(fileName).completeBaseName());
+}
+
+QSharedPointer<RunConfiguration> S60DeviceRunConfigurationFactory::create(Project *project, const QString &type)
+{
+    Qt4Project *p = qobject_cast<Qt4Project *>(project);
+    Q_ASSERT(p);
+    if (type.startsWith("QtS60DeviceRunConfiguration.")) {
+        QString fileName = type.mid(QString("QtS60DeviceRunConfiguration.").size());
+        return QSharedPointer<RunConfiguration>(new S60DeviceRunConfiguration(p, fileName));
+    }
+    Q_ASSERT(type == "Qt4ProjectManager.DeviceRunConfiguration");
+    // The right path is set in restoreSettings
+    QSharedPointer<RunConfiguration> rc(new S60DeviceRunConfiguration(p, QString::null));
+    return rc;
+}
+
+// ======== S60DeviceRunConfigurationRunner
+
+S60DeviceRunConfigurationRunner::S60DeviceRunConfigurationRunner(QObject *parent)
+    : IRunConfigurationRunner(parent)
+{
+}
+
+bool S60DeviceRunConfigurationRunner::canRun(QSharedPointer<RunConfiguration> runConfiguration, const QString &mode)
+{
+    return (mode == ProjectExplorer::Constants::RUNMODE)
+            && (!runConfiguration.dynamicCast<S60DeviceRunConfiguration>().isNull());
+}
+
+RunControl* S60DeviceRunConfigurationRunner::run(QSharedPointer<RunConfiguration> runConfiguration, const QString &mode)
+{
+    QSharedPointer<S60DeviceRunConfiguration> rc = runConfiguration.dynamicCast<S60DeviceRunConfiguration>();
+    Q_ASSERT(!rc.isNull());
+    Q_ASSERT(mode == ProjectExplorer::Constants::RUNMODE);
+
+    S60DeviceRunControl *runControl = new S60DeviceRunControl(rc);
+    return runControl;
+}
+
+// ======== S60DeviceRunControl
+
+S60DeviceRunControl::S60DeviceRunControl(QSharedPointer<RunConfiguration> runConfiguration)
+    : RunControl(runConfiguration)
+{
+    connect(&m_applicationLauncher, SIGNAL(applicationError(QString)),
+            this, SLOT(slotError(QString)));
+    connect(&m_applicationLauncher, SIGNAL(appendOutput(QString)),
+            this, SLOT(slotAddToOutputWindow(QString)));
+    connect(&m_applicationLauncher, SIGNAL(processExited(int)),
+            this, SLOT(processExited(int)));
+    connect(&m_applicationLauncher, SIGNAL(bringToForegroundRequested(qint64)),
+            this, SLOT(bringApplicationToForeground(qint64)));
+}
+
+void S60DeviceRunControl::start()
+{
+    QSharedPointer<S60DeviceRunConfiguration> rc = runConfiguration().dynamicCast<S60DeviceRunConfiguration>();
+    Q_ASSERT(!rc.isNull());
+
+    // stuff like the EPOCROOT and EPOCDEVICE env variable
+    Environment env = Environment::systemEnvironment();
+    static_cast<Qt4Project *>(rc->project())->toolChain(rc->project()->activeBuildConfiguration())->addToEnvironment(env);
+    m_applicationLauncher.setEnvironment(env.toStringList());
+
+    m_executable = rc->executable();
+
+    m_applicationLauncher.start(ApplicationLauncher::Gui,
+                                m_executable, QStringList());
+    emit started();
+
+    emit addToOutputWindow(this, tr("Starting %1...").arg(QDir::toNativeSeparators(m_executable)));
+}
+
+void S60DeviceRunControl::stop()
+{
+    m_applicationLauncher.stop();
+}
+
+bool S60DeviceRunControl::isRunning() const
+{
+    return m_applicationLauncher.isRunning();
+}
+
+void S60DeviceRunControl::slotError(const QString & err)
+{
+    emit error(this, err);
+    emit finished();
+}
+
+void S60DeviceRunControl::slotAddToOutputWindow(const QString &line)
+{
+    if (line.contains("Qt"))
+        emit addToOutputWindowInline(this, line);
+}
+
+void S60DeviceRunControl::processExited(int exitCode)
+{
+    emit addToOutputWindow(this, tr("%1 exited with code %2").arg(QDir::toNativeSeparators(m_executable)).arg(exitCode));
+    emit finished();
+}
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
new file mode 100644
index 0000000000000000000000000000000000000000..d1839f357c62d424e90a3e2536ade293f3aa588c
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
@@ -0,0 +1,107 @@
+#ifndef S60DEVICERUNCONFIGURATION_H
+#define S60DEVICERUNCONFIGURATION_H
+
+#include <projectexplorer/runconfiguration.h>
+#include <projectexplorer/applicationlauncher.h>
+
+#include <QtGui/QWidget>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+
+namespace Qt4ProjectManager {
+namespace Internal {
+
+class S60DeviceRunConfiguration : public ProjectExplorer::RunConfiguration
+{
+    Q_OBJECT
+public:
+    S60DeviceRunConfiguration(ProjectExplorer::Project *project, const QString &proFilePath);
+    ~S60DeviceRunConfiguration();
+
+    QString type() const;
+    bool isEnabled() const;
+    QWidget *configurationWidget();
+    void save(ProjectExplorer::PersistentSettingsWriter &writer) const;
+    void restore(const ProjectExplorer::PersistentSettingsReader &reader);
+
+    QString executable() const;
+
+signals:
+    void targetInformationChanged();
+
+private slots:
+    void invalidateCachedTargetInformation();
+
+private:
+    void updateTarget();
+
+    QString m_proFilePath;
+    QString m_executable;
+    bool m_cachedTargetInformationValid;
+};
+
+class S60DeviceRunConfigurationWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    S60DeviceRunConfigurationWidget(S60DeviceRunConfiguration *runConfiguration,
+                                      QWidget *parent = 0);
+
+private slots:
+    void nameEdited(const QString &text);
+    void updateTargetInformation();
+
+private:
+    S60DeviceRunConfiguration *m_runConfiguration;
+    QLineEdit *m_nameLineEdit;
+    QLabel *m_executableLabel;
+};
+
+class S60DeviceRunConfigurationFactory : public ProjectExplorer::IRunConfigurationFactory
+{
+    Q_OBJECT
+public:
+    S60DeviceRunConfigurationFactory(QObject *parent);
+    ~S60DeviceRunConfigurationFactory();
+    bool canRestore(const QString &type) const;
+    QStringList availableCreationTypes(ProjectExplorer::Project *pro) const;
+    // used to translate the types to names to display to the user
+    QString displayNameForType(const QString &type) const;
+    QSharedPointer<ProjectExplorer::RunConfiguration> create(ProjectExplorer::Project *project, const QString &type);
+};
+
+class S60DeviceRunConfigurationRunner : public ProjectExplorer::IRunConfigurationRunner
+{
+    Q_OBJECT
+public:
+    S60DeviceRunConfigurationRunner(QObject *parent = 0);
+    bool canRun(QSharedPointer<ProjectExplorer::RunConfiguration> runConfiguration, const QString &mode);
+    ProjectExplorer::RunControl* run(QSharedPointer<ProjectExplorer::RunConfiguration> runConfiguration, const QString &mode);
+    QString displayName() const { return "Run on Device"; }
+    QWidget *configurationWidget(QSharedPointer<ProjectExplorer::RunConfiguration> runConfiguration) { return 0; }
+};
+
+class S60DeviceRunControl : public ProjectExplorer::RunControl
+{
+    Q_OBJECT
+public:
+    S60DeviceRunControl(QSharedPointer<ProjectExplorer::RunConfiguration> runConfiguration);
+    ~S60DeviceRunControl() {}
+    void start();
+    void stop();
+    bool isRunning() const;
+
+private slots:
+    void processExited(int exitCode);
+    void slotAddToOutputWindow(const QString &line);
+    void slotError(const QString & error);
+
+private:
+    ProjectExplorer::ApplicationLauncher m_applicationLauncher;
+    QString m_executable;
+};
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
+
+#endif // S60DEVICERUNCONFIGURATION_H