diff --git a/src/rustup-cli/proxy_mode.rs b/src/rustup-cli/proxy_mode.rs
index 0c90d074fb..f865d927f7 100644
--- a/src/rustup-cli/proxy_mode.rs
+++ b/src/rustup-cli/proxy_mode.rs
@@ -49,7 +49,7 @@ pub fn main() -> Result<()> {
 fn direct_proxy(cfg: &Cfg, arg0: &str, toolchain: Option<&str>, args: &[OsString]) -> Result<()> {
     let cmd = match toolchain {
         None => try!(cfg.create_command_for_dir(&try!(utils::current_dir()), arg0)),
-        Some(tc) => try!(cfg.create_command_for_toolchain(tc, arg0)),
+        Some(tc) => try!(cfg.create_command_for_toolchain(tc, false, arg0)),
     };
     Ok(try!(run_command_for_dir(cmd, arg0, args, &cfg)))
 }
diff --git a/src/rustup-cli/rustup_mode.rs b/src/rustup-cli/rustup_mode.rs
index f306f57daa..21524e1b5a 100644
--- a/src/rustup-cli/rustup_mode.rs
+++ b/src/rustup-cli/rustup_mode.rs
@@ -277,6 +277,9 @@ pub fn cli() -> App<'static, 'static> {
             .about("Run a command with an environment configured for a given toolchain")
             .after_help(RUN_HELP)
             .setting(AppSettings::TrailingVarArg)
+            .arg(Arg::with_name("install")
+                .help("Install the requested toolchain if needed")
+                .long("install"))
             .arg(Arg::with_name("toolchain")
                 .help(TOOLCHAIN_ARG_HELP)
                 .required(true))
@@ -482,7 +485,7 @@ fn run(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
     let ref toolchain = m.value_of("toolchain").expect("");
     let args = m.values_of("command").unwrap();
     let args: Vec<_> = args.collect();
-    let cmd = try!(cfg.create_command_for_toolchain(toolchain, args[0]));
+    let cmd = try!(cfg.create_command_for_toolchain(toolchain, m.is_present("install"), args[0]));
 
     Ok(try!(command::run_command_for_dir(cmd, args[0], &args[1..], &cfg)))
 }
diff --git a/src/rustup/config.rs b/src/rustup/config.rs
index b35bd02766..e915dacbc9 100644
--- a/src/rustup/config.rs
+++ b/src/rustup/config.rs
@@ -410,8 +410,12 @@ impl Cfg {
         }
     }
 
-    pub fn create_command_for_toolchain(&self, toolchain: &str, binary: &str) -> Result<Command> {
+    pub fn create_command_for_toolchain(&self, toolchain: &str, install_if_missing: bool,
+                                        binary: &str) -> Result<Command> {
         let ref toolchain = try!(self.get_toolchain(toolchain, false));
+        if install_if_missing && !toolchain.exists() {
+            try!(toolchain.install_from_dist());
+        }
 
         if let Some(cmd) = try!(self.maybe_do_cargo_fallback(toolchain, binary)) {
             Ok(cmd)
diff --git a/tests/cli-misc.rs b/tests/cli-misc.rs
index ca02c3cb23..907b517575 100644
--- a/tests/cli-misc.rs
+++ b/tests/cli-misc.rs
@@ -320,6 +320,24 @@ fn rustup_failed_path_search() {
     });
 }
 
+#[test]
+fn rustup_run_not_installed() {
+    setup(&|config| {
+        expect_ok(config, &["rustup", "install", "stable"]);
+        expect_err(config, &["rustup", "run", "nightly", "rustc", "--version"],
+                   for_host!("toolchain 'nightly-{0}' is not installed"));
+    });
+}
+
+#[test]
+fn rustup_run_install() {
+    setup(&|config| {
+        expect_ok(config, &["rustup", "install", "stable"]);
+        expect_stderr_ok(config, &["rustup", "run", "--install", "nightly", "cargo", "--version"],
+                         "info: installing component 'rustc'");
+    });
+}
+
 #[test]
 fn multirust_env_compat() {
     setup(&|config| {