diff --git a/doc/src/howto/creator-external-tools.qdoc b/doc/src/howto/creator-external-tools.qdoc
index 1d29cd5ef428c72bcacbc197a5a7b2ab6755d135..60e769fb83c7616fcf9d83dff2b97220d5f017b0 100644
--- a/doc/src/howto/creator-external-tools.qdoc
+++ b/doc/src/howto/creator-external-tools.qdoc
@@ -115,6 +115,11 @@
         \li In the \uicontrol {Working directory} field, specify the path to the
             working directory.
 
+        \li In the \uicontrol Environment field, select \uicontrol Change to modify
+            environment variable values for build and run environments in
+            the \uicontrol {Edit Environment Changes} dialog. For more information
+            about how to add and remove variable values, see \l{Batch Editing}.
+
         \li In the \uicontrol {Output pane}, select how to handle output from the
             tool. You can ignore the output, view it in the \uicontrol {General
             Messages} output pane, or replace the selected text with the
diff --git a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp
index 35ba33a297b4073bb9f35d28eaa7f9487a46127d..80a69539a50d7662643458cd4c7985f6329c8fab 100644
--- a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp
+++ b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp
@@ -41,9 +41,11 @@
 #include <coreplugin/coreconstants.h>
 #include <coreplugin/variablechooser.h>
 
+#include <QDialogButtonBox>
 #include <QTextStream>
 #include <QMimeData>
 #include <QMenu>
+#include <QPlainTextEdit>
 
 using namespace Core;
 using namespace Core::Internal;
@@ -396,6 +398,44 @@ void ExternalToolModel::removeTool(const QModelIndex &modelIndex)
     delete tool;
 }
 
+EnvironmentChangesDialog::EnvironmentChangesDialog(QWidget *parent) :
+    QDialog(parent),
+    m_editor(0)
+{
+    setWindowTitle(tr("Edit Environment Changes"));
+    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+    setModal(true);
+
+    QVBoxLayout *layout = new QVBoxLayout(this);
+    QLabel *label = new QLabel(this);
+    label->setText(tr("Change system environment by assigning one environment variable per line:"));
+    layout->addWidget(label);
+
+    m_editor = new QPlainTextEdit(this);
+    if (Utils::HostOsInfo::isWindowsHost())
+        m_editor->setPlaceholderText(tr("PATH=C:\\dev\\bin;${PATH}"));
+    else
+        m_editor->setPlaceholderText(tr("PATH=/opt/bin:${PATH}"));
+
+    QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
+
+    layout->addWidget(m_editor);
+    layout->addWidget(buttons);
+
+    connect(buttons, &QDialogButtonBox::accepted, this, &EnvironmentChangesDialog::accept);
+    connect(buttons, &QDialogButtonBox::rejected, this, &EnvironmentChangesDialog::reject);
+}
+
+QStringList EnvironmentChangesDialog::changes() const
+{
+    return m_editor->toPlainText().split(QLatin1Char('\n'));
+}
+
+void EnvironmentChangesDialog::setChanges(const QStringList &changes)
+{
+    m_editor->setPlainText(changes.join(QLatin1Char('\n')));
+}
+
 // #pragma mark -- ExternalToolConfig
 
 ExternalToolConfig::ExternalToolConfig(QWidget *parent) :
@@ -423,6 +463,7 @@ ExternalToolConfig::ExternalToolConfig(QWidget *parent) :
     connect(ui->arguments, SIGNAL(editingFinished()), this, SLOT(updateEffectiveArguments()));
     connect(ui->workingDirectory, SIGNAL(editingFinished()), this, SLOT(updateCurrentItem()));
     connect(ui->workingDirectory, SIGNAL(browsingFinished()), this, SLOT(updateCurrentItem()));
+    connect(ui->environmentButton, SIGNAL(clicked()), this, SLOT(editEnvironmentChanges()));
     connect(ui->outputBehavior, SIGNAL(activated(int)), this, SLOT(updateCurrentItem()));
     connect(ui->errorOutputBehavior, SIGNAL(activated(int)), this, SLOT(updateCurrentItem()));
     connect(ui->modifiesDocumentCheckbox, SIGNAL(clicked()), this, SLOT(updateCurrentItem()));
@@ -510,6 +551,7 @@ void ExternalToolConfig::updateItem(const QModelIndex &index)
     tool->setExecutables(executables);
     tool->setArguments(ui->arguments->text());
     tool->setWorkingDirectory(ui->workingDirectory->rawPath());
+    tool->setEnvironment(Utils::EnvironmentItem::fromStringList(m_environment));
     tool->setOutputHandling((ExternalTool::OutputHandling)ui->outputBehavior->currentIndex());
     tool->setErrorHandling((ExternalTool::OutputHandling)ui->errorOutputBehavior->currentIndex());
     tool->setModifiesCurrentDocument(ui->modifiesDocumentCheckbox->checkState());
@@ -527,6 +569,7 @@ void ExternalToolConfig::showInfoForItem(const QModelIndex &index)
         ui->workingDirectory->setPath(QString());
         ui->inputText->clear();
         ui->infoWidget->setEnabled(false);
+        m_environment.clear();
         return;
     }
     ui->infoWidget->setEnabled(true);
@@ -537,6 +580,7 @@ void ExternalToolConfig::showInfoForItem(const QModelIndex &index)
     ui->outputBehavior->setCurrentIndex((int)tool->outputHandling());
     ui->errorOutputBehavior->setCurrentIndex((int)tool->errorHandling());
     ui->modifiesDocumentCheckbox->setChecked(tool->modifiesCurrentDocument());
+    m_environment = Utils::EnvironmentItem::toStringList(tool->environment());
 
     bool blocked = ui->inputText->blockSignals(true);
     ui->inputText->setPlainText(tool->input());
@@ -544,6 +588,7 @@ void ExternalToolConfig::showInfoForItem(const QModelIndex &index)
 
     ui->description->setCursorPosition(0);
     ui->arguments->setCursorPosition(0);
+    updateEnvironmentLabel();
     updateEffectiveArguments();
 }
 
@@ -596,3 +641,21 @@ void ExternalToolConfig::updateEffectiveArguments()
 {
     ui->arguments->setToolTip(Utils::globalMacroExpander()->expandProcessArgs(ui->arguments->text()));
 }
+
+void ExternalToolConfig::editEnvironmentChanges()
+{
+    EnvironmentChangesDialog dialog(ui->environmentLabel);
+    dialog.setChanges(m_environment);
+    if (dialog.exec() == QDialog::Accepted) {
+        m_environment = dialog.changes();
+        updateEnvironmentLabel();
+    }
+}
+
+void ExternalToolConfig::updateEnvironmentLabel()
+{
+    QString shortSummary = m_environment.join(QLatin1String("; "));
+    QFontMetrics fm(ui->environmentLabel->font());
+    shortSummary = fm.elidedText(shortSummary, Qt::ElideRight, ui->environmentLabel->width());
+    ui->environmentLabel->setText(shortSummary.isEmpty() ? tr("No Changes to apply") : shortSummary);
+}
diff --git a/src/plugins/coreplugin/dialogs/externaltoolconfig.h b/src/plugins/coreplugin/dialogs/externaltoolconfig.h
index 40ac508f8aeabb5183f887414ef0d47a5425e866..f68b15c6a912d73d5b7a834491e3939a4f9c72c5 100644
--- a/src/plugins/coreplugin/dialogs/externaltoolconfig.h
+++ b/src/plugins/coreplugin/dialogs/externaltoolconfig.h
@@ -35,6 +35,9 @@
 
 #include <QWidget>
 #include <QAbstractItemModel>
+#include <QDialog>
+
+QT_FORWARD_DECLARE_CLASS(QPlainTextEdit)
 
 namespace Core {
 namespace Internal {
@@ -82,6 +85,17 @@ private:
     QMap<QString, QList<ExternalTool *> > m_tools;
 };
 
+class EnvironmentChangesDialog : public QDialog
+{
+    Q_OBJECT
+public:
+    explicit EnvironmentChangesDialog(QWidget *parent = 0);
+
+    QStringList changes() const;
+    void setChanges(const QStringList &changes);
+private:
+    QPlainTextEdit *m_editor;
+};
 
 class ExternalToolConfig : public QWidget
 {
@@ -106,9 +120,12 @@ private slots:
     void removeTool();
     void addCategory();
     void updateEffectiveArguments();
+    void editEnvironmentChanges();
+    void updateEnvironmentLabel();
 
 private:
     Ui::ExternalToolConfig *ui;
+    QStringList m_environment;
     ExternalToolModel *m_model;
 };
 
diff --git a/src/plugins/coreplugin/dialogs/externaltoolconfig.ui b/src/plugins/coreplugin/dialogs/externaltoolconfig.ui
index c3302139787b20da9bca0f75c0e00e632f1743a9..39beea463978743cf9de25acc3bb4567d71dc298 100644
--- a/src/plugins/coreplugin/dialogs/externaltoolconfig.ui
+++ b/src/plugins/coreplugin/dialogs/externaltoolconfig.ui
@@ -210,7 +210,41 @@
         </item>
        </widget>
       </item>
+      <item row="6" column="0">
+       <widget class="QLabel" name="label_2">
+        <property name="text">
+         <string>Environment:</string>
+        </property>
+       </widget>
+      </item>
       <item row="6" column="1">
+       <layout class="QHBoxLayout" name="horizontalLayout_3">
+        <property name="spacing">
+         <number>0</number>
+        </property>
+        <item>
+         <widget class="QLabel" name="environmentLabel">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="text">
+           <string>No Changes to apply.</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="environmentButton">
+          <property name="text">
+           <string>Change...</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item row="7" column="1">
        <widget class="QCheckBox" name="modifiesDocumentCheckbox">
         <property name="toolTip">
          <string>If the tool modifies the current document, set this flag to ensure that the document is saved before running the tool and is reloaded after the tool finished.</string>
@@ -220,7 +254,7 @@
         </property>
        </widget>
       </item>
-      <item row="7" column="0">
+      <item row="8" column="0">
        <widget class="QLabel" name="inputLabel">
         <property name="toolTip">
          <string>Text to pass to the executable via standard input. Leave empty if the executable should not receive any input.</string>
@@ -230,7 +264,7 @@
         </property>
        </widget>
       </item>
-      <item row="7" column="1">
+      <item row="8" column="1">
        <widget class="QPlainTextEdit" name="inputText">
         <property name="lineWrapMode">
          <enum>QPlainTextEdit::NoWrap</enum>
diff --git a/src/plugins/coreplugin/externaltool.cpp b/src/plugins/coreplugin/externaltool.cpp
index 13e696d12a86a7883d157ea7af328e258ee047f6..a006f4de6194a0e80dcb4a93f7081a266fd501f6 100644
--- a/src/plugins/coreplugin/externaltool.cpp
+++ b/src/plugins/coreplugin/externaltool.cpp
@@ -66,6 +66,7 @@ const char kPath[] = "path";
 const char kArguments[] = "arguments";
 const char kInput[] = "input";
 const char kWorkingDirectory[] = "workingdirectory";
+const char kEnvironment[] = "environment";
 
 const char kXmlLang[] = "xml:lang";
 const char kOutput[] = "output";
@@ -100,6 +101,7 @@ ExternalTool::ExternalTool(const ExternalTool *other)
       m_arguments(other->m_arguments),
       m_input(other->m_input),
       m_workingDirectory(other->m_workingDirectory),
+      m_environment(other->m_environment),
       m_outputHandling(other->m_outputHandling),
       m_errorHandling(other->m_errorHandling),
       m_modifiesCurrentDocument(other->m_modifiesCurrentDocument),
@@ -119,6 +121,7 @@ ExternalTool &ExternalTool::operator=(const ExternalTool &other)
     m_arguments = other.m_arguments;
     m_input = other.m_input;
     m_workingDirectory = other.m_workingDirectory;
+    m_environment = other.m_environment;
     m_outputHandling = other.m_outputHandling;
     m_errorHandling = other.m_errorHandling;
     m_modifiesCurrentDocument = other.m_modifiesCurrentDocument;
@@ -177,6 +180,11 @@ QString ExternalTool::workingDirectory() const
     return m_workingDirectory;
 }
 
+QList<Utils::EnvironmentItem> ExternalTool::environment() const
+{
+    return m_environment;
+}
+
 ExternalTool::OutputHandling ExternalTool::outputHandling() const
 {
     return m_outputHandling;
@@ -274,6 +282,11 @@ void ExternalTool::setWorkingDirectory(const QString &workingDirectory)
     m_workingDirectory = workingDirectory;
 }
 
+void ExternalTool::setEnvironment(const QList<Utils::EnvironmentItem> &items)
+{
+    m_environment = items;
+}
+
 static QStringList splitLocale(const QString &locale)
 {
     QString value = locale;
@@ -408,6 +421,15 @@ ExternalTool * ExternalTool::createFromXml(const QByteArray &xml, QString *error
                         break;
                     }
                     tool->m_workingDirectory = reader.readElementText();
+                } else if (reader.name() == QLatin1String(kEnvironment)) {
+                    if (!tool->m_environment.isEmpty()) {
+                        reader.raiseError(QLatin1String("only one <environment> element allowed"));
+                        break;
+                    }
+                    QStringList lines = reader.readElementText().split(QLatin1Char(';'));
+                    for (auto iter = lines.begin(); iter != lines.end(); ++iter)
+                        *iter = QString::fromUtf8(QByteArray::fromPercentEncoding(iter->toUtf8()));
+                    tool->m_environment = Utils::EnvironmentItem::fromStringList(lines);
                 } else {
                     reader.raiseError(QString::fromLatin1("Unknown element <%1> as subelement of <%2>").arg(
                                           reader.qualifiedName().toString(), QLatin1String(kExecutable)));
@@ -484,6 +506,12 @@ bool ExternalTool::save(QString *errorMessage) const
             out.writeTextElement(QLatin1String(kInput), m_input);
         if (!m_workingDirectory.isEmpty())
             out.writeTextElement(QLatin1String(kWorkingDirectory), m_workingDirectory);
+        if (!m_environment.isEmpty()) {
+            QStringList envLines = Utils::EnvironmentItem::toStringList(m_environment);
+            for (auto iter = envLines.begin(); iter != envLines.end(); ++iter)
+                *iter = QString::fromUtf8(iter->toUtf8().toPercentEncoding());
+            out.writeTextElement(QLatin1String(kEnvironment), envLines.join(QLatin1Char(';')));
+        }
         out.writeEndElement();
 
         out.writeEndDocument();
@@ -504,6 +532,7 @@ bool ExternalTool::operator==(const ExternalTool &other) const
             && m_arguments == other.m_arguments
             && m_input == other.m_input
             && m_workingDirectory == other.m_workingDirectory
+            && m_environment == other.m_environment
             && m_outputHandling == other.m_outputHandling
             && m_modifiesCurrentDocument == other.m_modifiesCurrentDocument
             && m_errorHandling == other.m_errorHandling
@@ -544,14 +573,19 @@ bool ExternalToolRunner::resolve()
     m_resolvedExecutable.clear();
     m_resolvedArguments.clear();
     m_resolvedWorkingDirectory.clear();
+    m_resolvedEnvironment = Utils::Environment::systemEnvironment();
+
 
     MacroExpander *expander = globalMacroExpander();
-    { // executable
+    m_resolvedEnvironment.modify(m_tool->environment());
+
+    {
+        // executable
         QStringList expandedExecutables; /* for error message */
         foreach (const QString &executable, m_tool->executables()) {
             QString expanded = expander->expand(executable);
             expandedExecutables.append(expanded);
-            m_resolvedExecutable = Environment::systemEnvironment().searchInPath(expanded);
+            m_resolvedExecutable = m_resolvedEnvironment.searchInPath(expanded);
             if (!m_resolvedExecutable.isEmpty())
                 break;
         }
@@ -601,6 +635,7 @@ void ExternalToolRunner::run()
     if (!m_resolvedWorkingDirectory.isEmpty())
         m_process->setWorkingDirectory(m_resolvedWorkingDirectory);
     m_process->setCommand(m_resolvedExecutable.toString(), m_resolvedArguments);
+    m_process->setEnvironment(m_resolvedEnvironment);
     MessageManager::write(tr("Starting external tool \"%1\" %2")
                           .arg(m_resolvedExecutable.toUserOutput(), m_resolvedArguments),
                           MessageManager::Silent);
diff --git a/src/plugins/coreplugin/externaltool.h b/src/plugins/coreplugin/externaltool.h
index 636b4c1bd2dfa3485ef55fd3feeba8e543099d45..4846b2b15e365c071e8a44e0acdfe3d39213719b 100644
--- a/src/plugins/coreplugin/externaltool.h
+++ b/src/plugins/coreplugin/externaltool.h
@@ -32,6 +32,7 @@
 #define EXTERNALTOOL_H
 
 #include <utils/fileutils.h>
+#include <utils/environment.h>
 
 #include <QObject>
 #include <QStringList>
@@ -72,6 +73,7 @@ public:
     QString arguments() const;
     QString input() const;
     QString workingDirectory() const;
+    QList<Utils::EnvironmentItem> environment() const;
 
     void setFileName(const QString &fileName);
     void setPreset(QSharedPointer<ExternalTool> preset);
@@ -100,6 +102,7 @@ public:
     void setArguments(const QString &arguments);
     void setInput(const QString &input);
     void setWorkingDirectory(const QString &workingDirectory);
+    void setEnvironment(const QList<Utils::EnvironmentItem> &items);
 
 private:
     QString m_id;
@@ -111,6 +114,7 @@ private:
     QString m_arguments;
     QString m_input;
     QString m_workingDirectory;
+    QList<Utils::EnvironmentItem> m_environment;
     OutputHandling m_outputHandling;
     OutputHandling m_errorHandling;
     bool m_modifiesCurrentDocument;
@@ -146,6 +150,7 @@ private:
     QString m_resolvedArguments;
     QString m_resolvedInput;
     QString m_resolvedWorkingDirectory;
+    Utils::Environment m_resolvedEnvironment;
     Utils::QtcProcess *m_process;
     QTextCodec *m_outputCodec;
     QTextCodec::ConverterState m_outputCodecState;