diff --git a/NEWS b/NEWS
index a0692ce8cae7923bb8493860b087d51efadc13c4..fe81829a2c16d84c6d9d8d392bbe885f94a8f2c5 100644
--- a/NEWS
+++ b/NEWS
@@ -3,9 +3,12 @@ documents those changes that are of interest to users and admins.
 
 * Changes in SLURM 1.4.0-pre7
 =============================
- -- Bug fix for preemtpion with select/cons_res when there are no idle nodes.
+ -- Bug fix for preemption with select/cons_res when there are no idle nodes.
  -- Bug fix for use of srun options --exclusive and --cpus-per-task together
     for job step resource allocation (tracking of cpus in use was bad).
+ -- Added the srun option --preserve-env to pass the current values of 
+    environment variables SLURM_NNODES and SLURM_NPROCS through to the 
+    executable, rather than computing them from commandline parameters.
 
 * Changes in SLURM 1.4.0-pre6
 =============================
diff --git a/doc/man/man1/srun.1 b/doc/man/man1/srun.1
index d2adb07a3323218b838e441500ef737a7f096154..bd99bd0cbeff82b4de99257ab4233431d341f058 100644
--- a/doc/man/man1/srun.1
+++ b/doc/man/man1/srun.1
@@ -263,6 +263,12 @@ redirected to different locations.
 See \fBIO Redirection\fR below for more options.
 If the specified file already exists, it will be overwritten.
 
+.TP
+\fB\-E\fR, \fB\-\-preserve-env\fR
+Pass the current values of environment variables SLURM_NNODES and 
+SLURM_NPROCS through to the \fIexecutable\fR, rather than computing them
+from commandline parameters.
+
 .TP
 \fB\-\-epilog\fR=\fIexecutable\fR
 \fBsrun\fR will run \fIexecutable\fR just after the job step completes.
diff --git a/src/api/step_launch.c b/src/api/step_launch.c
index aa4bcf62e6c4b2ad41ddf141ac009a75569339ee..e793c9a8421d3ea0e26452d8a650461eae1a44fa 100644
--- a/src/api/step_launch.c
+++ b/src/api/step_launch.c
@@ -195,7 +195,8 @@ int slurm_step_launch (slurm_step_ctx_t *ctx,
 		env_array_merge(&env, (const char **)params->env);
 	}
 	env_array_for_step(&env, ctx->step_resp,
-			   ctx->launch_state->resp_port[0]);
+			   ctx->launch_state->resp_port[0], 
+			   params->preserve_env);
 	env_array_merge(&env, (const char **)mpi_env);
 	env_array_free(mpi_env);
 
diff --git a/src/common/env.c b/src/common/env.c
index ec95f12ed207073bb1986a1d2d8837f0ed512161..d111a1c21abf4d9d003f49dcc77ae597def4f3bd 100644
--- a/src/common/env.c
+++ b/src/common/env.c
@@ -956,7 +956,8 @@ env_array_for_batch_job(char ***dest, const batch_job_launch_msg_t *batch,
  * overwriting any environment variables of the same name.  If the address
  * pointed to by "dest" is NULL, memory will automatically be xmalloc'ed.
  * The array is terminated by a NULL pointer, and thus is suitable for
- * use by execle() and other env_array_* functions.
+ * use by execle() and other env_array_* functions.  If preserve_env is
+ * true, the variables SLURM_NNODES and SLURM_NPROCS remain unchanged.
  *
  * Sets variables:
  *	SLURM_STEP_ID
@@ -979,7 +980,8 @@ env_array_for_batch_job(char ***dest, const batch_job_launch_msg_t *batch,
 void
 env_array_for_step(char ***dest, 
 		   const job_step_create_response_msg_t *step,
-		   uint16_t launcher_port)
+		   uint16_t launcher_port,
+		   bool preserve_env)
 {
 	char *tmp;
 
@@ -998,10 +1000,12 @@ env_array_for_step(char ***dest,
 
 	/* OBSOLETE, but needed by MPI, do not remove */
 	env_array_overwrite_fmt(dest, "SLURM_STEPID", "%u", step->job_step_id);
-	env_array_overwrite_fmt(dest, "SLURM_NNODES",
-				"%hu", step->step_layout->node_cnt);
-	env_array_overwrite_fmt(dest, "SLURM_NPROCS",
-				"%u", step->step_layout->task_cnt);
+	if (!preserve_env) {
+		env_array_overwrite_fmt(dest, "SLURM_NNODES",
+					"%hu", step->step_layout->node_cnt);
+		env_array_overwrite_fmt(dest, "SLURM_NPROCS",
+					"%u", step->step_layout->task_cnt);
+	}
 	env_array_overwrite_fmt(dest, "SLURM_TASKS_PER_NODE", "%s", tmp);
 	env_array_overwrite_fmt(dest, "SLURM_SRUN_COMM_PORT",
 				"%hu", launcher_port);
diff --git a/src/common/env.h b/src/common/env.h
index 6c577dab44024a1d5e9ab9e247fc5c78404ba9a9..44581572bd249c53f66035d5fcc4a0914dc63a16 100644
--- a/src/common/env.h
+++ b/src/common/env.h
@@ -135,11 +135,12 @@ extern void env_array_for_batch_job(char ***dest,
 				    const char* node_name);
 
 /*
- * Set in "dest the environment variables relevant to a SLURM job step,
+ * Set in "dest" the environment variables relevant to a SLURM job step,
  * overwriting any environment variables of the same name.  If the address
  * pointed to by "dest" is NULL, memory will automatically be xmalloc'ed.
  * The array is terminated by a NULL pointer, and thus is suitable for
- * use by execle() and other env_array_* functions.
+ * use by execle() and other env_array_* functions.  If preserve_env is
+ * true, the variables SLURM_NNODES and SLURM_NPROCS remain unchanged.
  *
  * Sets variables:
  *	SLURM_STEP_ID
@@ -163,7 +164,8 @@ extern void env_array_for_batch_job(char ***dest,
 void
 env_array_for_step(char ***dest,
 		   const job_step_create_response_msg_t *step,
-		   uint16_t launcher_port);
+		   uint16_t launcher_port,
+		   bool preserve_env);
 
 /*
  * Return an empty environment variable array (contains a single
diff --git a/src/srun/opt.c b/src/srun/opt.c
index f580524362de9c5928836c9e6568e518ccc68032..a04056d6777d19368a945e6987c36fec87147f04 100644
--- a/src/srun/opt.c
+++ b/src/srun/opt.c
@@ -377,6 +377,7 @@ static void _opt_default()
 	opt.quit_on_intr = false;
 	opt.disable_status = false;
 	opt.test_only   = false;
+	opt.preserve_env = false;
 
 	opt.quiet = 0;
 	_verbose = 0;
@@ -679,6 +680,7 @@ static void set_options(const int argc, char **argv)
 		{"slurmd-debug",  required_argument, 0, 'd'},
 		{"chdir",         required_argument, 0, 'D'},
 		{"error",         required_argument, 0, 'e'},
+		{"preserve-env",  no_argument,       0, 'E'},
 		{"geometry",      required_argument, 0, 'g'},
 		{"hold",          no_argument,       0, 'H'},
 		{"input",         required_argument, 0, 'i'},
@@ -770,7 +772,7 @@ static void set_options(const int argc, char **argv)
 		{"wckey",            required_argument, 0, LONG_OPT_WCKEY},
 		{NULL,               0,                 0, 0}
 	};
-	char *opt_string = "+aAbB:c:C:d:D:e:g:Hi:IjJ:kKlL:m:n:N:"
+	char *opt_string = "+aAbB:c:C:d:D:e:Eg:Hi:IjJ:kKlL:m:n:N:"
 		"o:Op:P:qQr:R:st:T:uU:vVw:W:x:XZ";
 
 	struct option *optz = spank_option_table_create (long_options);
@@ -851,6 +853,9 @@ static void set_options(const int argc, char **argv)
 			else
 				opt.efname = xstrdup(optarg);
 			break;
+		case (int)'E':
+			opt.preserve_env = true;
+			break;
 		case (int)'g':
 			if (verify_geometry(optarg, opt.geometry))
 				exit(1);
@@ -1878,6 +1883,7 @@ static void _opt_list()
 	xfree(str);
 	info("reboot         : %s", opt.reboot ? "no" : "yes");
 	info("rotate         : %s", opt.no_rotate ? "yes" : "no");
+	info("preserve_env   : %s", tf_(opt.preserve_env));
 	
 	if (opt.blrtsimage)
 		info("BlrtsImage     : %s", opt.blrtsimage);
@@ -1925,6 +1931,7 @@ static bool _under_parallel_debugger (void)
 	return (MPIR_being_debugged != 0);
 }
 
+
 static void _usage(void)
 {
  	printf(
@@ -1940,7 +1947,7 @@ static void _usage(void)
 "            [--kill-on-bad-exit] [--propagate[=rlimits] [--comment=name]\n"
 "            [--cpu_bind=...] [--mem_bind=...] [--network=type]\n"
 "            [--ntasks-per-node=n] [--ntasks-per-socket=n]\n"
-"            [--ntasks-per-core=n] [--mem-per-cpu=MB]\n"
+"            [--ntasks-per-core=n] [--mem-per-cpu=MB] [--preserve-env]\n"
 #ifdef HAVE_BG		/* Blue gene specific options */
 "            [--geometry=XxYxZ] [--conn-type=type] [--no-rotate] [--reboot]\n"
 "            [--blrts-image=path] [--linux-image=path]\n"
@@ -2015,6 +2022,7 @@ static void _help(void)
 "  -L, --licenses=names        required license, comma separated\n"
 "      --checkpoint=time       job step checkpoint interval\n"
 "      --checkpoint-path=dir   path to store job step checkpoint image files\n"
+"  -E, --preserve-env          env vars for node and task counts override command-line flags\n"
 #ifdef HAVE_PTY_H
 "      --pty                   run task zero in pseudo terminal\n"
 #endif
diff --git a/src/srun/opt.h b/src/srun/opt.h
index 1d64ff587eeec87f70cc263a35e0f58841b7e958..c273790ce615c41b27eb3318ac29143eb83c4f9d 100644
--- a/src/srun/opt.h
+++ b/src/srun/opt.h
@@ -165,6 +165,7 @@ typedef struct srun_options {
 	char *task_epilog;	/* --task-epilog=		*/
 	char *task_prolog;	/* --task-prolog=		*/
 	char *licenses;		/* --licenses, -L		*/
+	bool preserve_env;	/* --preserve-env		*/
 
 	/* constraint options */
 	int32_t job_min_cpus;	/* --mincpus=n			*/
diff --git a/src/srun/srun.c b/src/srun/srun.c
index faa28e8dfa7aa03c3545be17411e8f1fd420046b..7709ad8daa5fa06fab9826f1c645524855db5d8e 100644
--- a/src/srun/srun.c
+++ b/src/srun/srun.c
@@ -290,7 +290,6 @@ int srun(int ac, char **av)
 	/*
 	 *  Enhance environment for job
 	 */
-	env->nprocs = opt.nprocs;
 	env->cpus_per_task = opt.cpus_per_task;
 	if (opt.ntasks_per_node != NO_VAL)
 		env->ntasks_per_node = opt.ntasks_per_node;
@@ -315,7 +314,6 @@ int srun(int ac, char **av)
 				   &tasks);
 
 		env->select_jobinfo = job->select_jobinfo;
-		env->nhosts = job->nhosts;
 		env->nodelist = job->nodelist;
 		env->task_count = _uint16_array_to_str(
 			job->nhosts, tasks);
@@ -377,6 +375,7 @@ int srun(int ac, char **av)
 	launch_params.ntasks_per_core   = opt.ntasks_per_core;
 	launch_params.task_dist         = opt.distribution;
 	launch_params.ckpt_path		= xstrdup(opt.ckpt_path);
+	launch_params.preserve_env      = opt.preserve_env;
 	/* job structure should now be filled in */
 	_setup_signals();