diff --git a/doc/man/man1/srun.1 b/doc/man/man1/srun.1
index 1d592eee40736da65660faf6f4b7f48e73bc1b27..b78b7d96744dc23a79a274bffc45cc9a7fb0a9a9 100644
--- a/doc/man/man1/srun.1
+++ b/doc/man/man1/srun.1
@@ -131,6 +131,13 @@ If not specified, the scontrol show job will display 'ReqS:C:T=*:*:*'.
 .TP
 \fB\-\-bb\fR=<\fIspec\fR>
 Burst buffer specification. The form of the specification is system dependent.
+Also see \fB\-\-bbf\fR.
+
+.TP
+\fB\-\-bbf\fR=<\fIfile_name\fR>
+Path of file containing burst buffer specification.
+The form of the specification is system dependent.
+Also see \fB\-\-bb\fR.
 
 .TP
 \fB\-\-begin\fR=<\fItime\fR>
diff --git a/src/salloc/opt.c b/src/salloc/opt.c
index 1ee01e6ebf0e4277c6f59cb45e25274bc4b455d1..5cce18f665bda496da3a18eb7a6d501e3b564e28 100644
--- a/src/salloc/opt.c
+++ b/src/salloc/opt.c
@@ -157,7 +157,8 @@
 #define LONG_OPT_GET_USER_ENV    0x125
 #define LONG_OPT_NETWORK         0x126
 #define LONG_OPT_QOS             0x127
-#define LONG_OPT_BURST_BUFFER    0x128
+#define LONG_OPT_BURST_BUFFER_SPEC  0x128
+#define LONG_OPT_BURST_BUFFER_FILE  0x129
 #define LONG_OPT_SOCKETSPERNODE  0x130
 #define LONG_OPT_CORESPERSOCKET  0x131
 #define LONG_OPT_THREADSPERCORE  0x132
@@ -206,9 +207,10 @@ static void  _opt_list(void);
 
 /* verify options sanity  */
 static bool _opt_verify(void);
-
+static char *_read_file(char *fname);
 static void  _proc_get_user_env(char *optarg);
 static void _process_env_var(env_vars_t *e, const char *val);
+
 static void  _usage(void);
 
 /*---[ end forward declarations of static functions ]---------------------*/
@@ -675,7 +677,8 @@ void set_options(const int argc, char **argv)
 		{"exclude",       required_argument, 0, 'x'},
 		{"acctg-freq",    required_argument, 0, LONG_OPT_ACCTG_FREQ},
 		{"begin",         required_argument, 0, LONG_OPT_BEGIN},
-		{"bb",            required_argument, 0, LONG_OPT_BURST_BUFFER},
+		{"bb",            required_argument, 0, LONG_OPT_BURST_BUFFER_SPEC},
+		{"bbf",           required_argument, 0, LONG_OPT_BURST_BUFFER_FILE},
 		{"bell",          no_argument,       0, LONG_OPT_BELL},
 		{"blrts-image",   required_argument, 0, LONG_OPT_BLRTS_IMAGE},
 		{"cnload-image",  required_argument, 0, LONG_OPT_LINUX_IMAGE},
@@ -1245,10 +1248,14 @@ void set_options(const int argc, char **argv)
 			}
 			opt.req_switch = parse_int("switches", optarg, true);
 			break;
-		case LONG_OPT_BURST_BUFFER:
+		case LONG_OPT_BURST_BUFFER_SPEC:
 			xfree(opt.burst_buffer);
 			opt.burst_buffer = xstrdup(optarg);
 			break;
+		case LONG_OPT_BURST_BUFFER_FILE:
+			xfree(opt.burst_buffer);
+			opt.burst_buffer = _read_file(optarg);
+			break;
 		case LONG_OPT_THREAD_SPEC:
 			opt.core_spec = parse_int("thread_spec", optarg, true) |
 				CORE_SPEC_THREAD;
@@ -1743,6 +1750,40 @@ extern int   spank_unset_job_env(const char *name)
 	return 0;	/* not found */
 }
 
+/* Read specified file's contents into a buffer.
+ * Caller must xfree the buffer's contents */
+static char *_read_file(char *fname)
+{
+	int fd, i, offset = 0;
+	struct stat stat_buf;
+	char *file_buf;
+
+	fd = open(fname, O_RDONLY);
+	if (fd < 0) {
+		fatal("Could not open burst buffer specification file %s: %m",
+		      fname);
+	}
+	if (fstat(fd, &stat_buf) < 0) {
+		fatal("Could not stat burst buffer specification file %s: %m",
+		      fname);
+	}
+	file_buf = xmalloc(stat_buf.st_size);
+	while (stat_buf.st_size > offset) {
+		i = read(fd, file_buf + offset, stat_buf.st_size - offset);
+		if (i < 0) {
+			if (errno == EAGAIN)
+				continue;
+			fatal("Could not read burst buffer specification "
+			      "file %s: %m", fname);
+		}
+		if (i == 0)
+			break;	/* EOF */
+		offset += i;
+	}
+	close(fd);
+	return file_buf;
+}
+
 /* helper function for printing options
  *
  * warning: returns pointer to memory allocated on the stack.
@@ -1936,7 +1977,8 @@ static void _usage(void)
 "              [--cpu-freq=min[-max[:gov]] [--sicp] [--power=flags]\n"
 "              [--switches=max-switches[@max-time-to-wait]]\n"
 "              [--core-spec=cores] [--thread-spec=threads] [--reboot]\n"
-"              [--bb=burst_buffer_spec] [executable [args...]]\n");
+"              [--bb=burst_buffer_spec] [--bbf=burst_buffer_file]\n"
+"              [executable [args...]]\n");
 }
 
 static void _help(void)
@@ -1951,6 +1993,7 @@ static void _help(void)
 "      --begin=time            defer job until HH:MM MM/DD/YY\n"
 "      --bell                  ring the terminal bell when the job is allocated\n"
 "      --bb=<spec>             burst buffer specifications\n"
+"      --bbf=<file_name>       burst buffer specification file\n"
 "  -c, --cpus-per-task=ncpus   number of cpus required per task\n"
 "      --comment=name          arbitrary comment\n"
 "      --cpu-freq=min[-max[:gov]] requested cpu frequency (and governor)\n"
diff --git a/src/srun/libsrun/opt.c b/src/srun/libsrun/opt.c
index 5835b844f15e841c0c898d94bc342f331df5346a..5beb47390874c97da10d94ac4ba7b4b457f935c1 100644
--- a/src/srun/libsrun/opt.c
+++ b/src/srun/libsrun/opt.c
@@ -68,9 +68,10 @@
 #include <stdio.h>
 #include <stdlib.h>		/* getenv     */
 #include <sys/param.h>		/* MAXPATHLEN */
-#include <unistd.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/utsname.h>
+#include <unistd.h>
 
 #include "src/common/cpu_frequency.h"
 #include "src/common/list.h"
@@ -167,7 +168,8 @@
 #define LONG_OPT_MULTI       0x122
 #define LONG_OPT_COMMENT     0x124
 #define LONG_OPT_QOS             0x127
-#define LONG_OPT_BURST_BUFFER    0x128
+#define LONG_OPT_BURST_BUFFER_SPEC  0x128
+#define LONG_OPT_BURST_BUFFER_FILE  0x129
 #define LONG_OPT_SOCKETSPERNODE  0x130
 #define LONG_OPT_CORESPERSOCKET	 0x131
 #define LONG_OPT_THREADSPERCORE  0x132
@@ -243,7 +245,7 @@ static void  _opt_list(void);
 static bool _opt_verify(void);
 
 static void _process_env_var(env_vars_t *e, const char *val);
-
+static char *_read_file(char *fname);
 static bool  _under_parallel_debugger(void);
 static void  _usage(void);
 static bool  _valid_node_list(char **node_list_pptr);
@@ -900,7 +902,8 @@ static void _set_options(const int argc, char **argv)
 		{"no-allocate",   no_argument,       0, 'Z'},
 		{"accel-bind",       required_argument, 0, LONG_OPT_ACCEL_BIND},
 		{"acctg-freq",       required_argument, 0, LONG_OPT_ACCTG_FREQ},
-		{"bb",               required_argument, 0, LONG_OPT_BURST_BUFFER},
+		{"bb",               required_argument, 0, LONG_OPT_BURST_BUFFER_SPEC},
+		{"bbf",              required_argument, 0, LONG_OPT_BURST_BUFFER_FILE},
 		{"begin",            required_argument, 0, LONG_OPT_BEGIN},
 		{"blrts-image",      required_argument, 0, LONG_OPT_BLRTS_IMAGE},
 		{"checkpoint",       required_argument, 0, LONG_OPT_CHECKPOINT},
@@ -1423,10 +1426,14 @@ static void _set_options(const int argc, char **argv)
 			xfree(opt.epilog);
 			opt.epilog = xstrdup(optarg);
 			break;
-		case LONG_OPT_BURST_BUFFER:
+		case LONG_OPT_BURST_BUFFER_SPEC:
 			xfree(opt.burst_buffer);
 			opt.burst_buffer = xstrdup(optarg);
 			break;
+		case LONG_OPT_BURST_BUFFER_FILE:
+			xfree(opt.burst_buffer);
+			opt.burst_buffer = _read_file(optarg);
+			break;
 		case LONG_OPT_BEGIN:
 			opt.begin = parse_time(optarg, 0);
 			if (errno == ESLURM_INVALID_TIME_VALUE) {
@@ -2544,6 +2551,40 @@ static void _opt_list(void)
 
 }
 
+/* Read specified file's contents into a buffer.
+ * Caller must xfree the buffer's contents */
+static char *_read_file(char *fname)
+{
+	int fd, i, offset = 0;
+	struct stat stat_buf;
+	char *file_buf;
+
+	fd = open(fname, O_RDONLY);
+	if (fd < 0) {
+		fatal("Could not open burst buffer specification file %s: %m",
+		      fname);
+	}
+	if (fstat(fd, &stat_buf) < 0) {
+		fatal("Could not stat burst buffer specification file %s: %m",
+		      fname);
+	}
+	file_buf = xmalloc(stat_buf.st_size);
+	while (stat_buf.st_size > offset) {
+		i = read(fd, file_buf + offset, stat_buf.st_size - offset);
+		if (i < 0) {
+			if (errno == EAGAIN)
+				continue;
+			fatal("Could not read burst buffer specification "
+			      "file %s: %m", fname);
+		}
+		if (i == 0)
+			break;	/* EOF */
+		offset += i;
+	}
+	close(fd);
+	return file_buf;
+}
+
 /* Determine if srun is under the control of a parallel debugger or not */
 static bool _under_parallel_debugger (void)
 {
@@ -2597,7 +2638,8 @@ static void _usage(void)
 "            [--ctrl-comm-ifhn=addr] [--multi-prog]\n"
 "            [--cpu-freq=min[-max[:gov]] [--sicp] [--power=flags]\n"
 "            [--switches=max-switches{@max-time-to-wait}] [--reboot]\n"
-"            [--core-spec=cores] [--thread-spec=threads] [--bb=burst_buffer_spec]\n"
+"            [--core-spec=cores] [--thread-spec=threads]\n"
+"            [--bb=burst_buffer_spec] [--bbf=burst_buffer_file]\n"
 "            [--acctg-freq=<datatype>=<interval>\n"
 "            [-w hosts...] [-x hosts...] executable [args...]\n");
 
@@ -2617,6 +2659,7 @@ static void _help(void)
 "                              task=<interval> energy=<interval>\n"
 "                              network=<interval> filesystem=<interval>\n"
 "      --bb=<spec>             burst buffer specifications\n"
+"      --bbf=<file_name>       burst buffer specification file\n"
 "      --begin=time            defer job until HH:MM MM/DD/YY\n"
 "  -c, --cpus-per-task=ncpus   number of cpus required per task\n"
 "      --checkpoint=time       job step checkpoint interval\n"