diff --git a/varnish-cache/bin/varnishd/cache_vcl.c b/varnish-cache/bin/varnishd/cache_vcl.c
index 249a4f8..47e8c18 100644
--- a/varnish-cache/bin/varnishd/cache_vcl.c
+++ b/varnish-cache/bin/varnishd/cache_vcl.c
@@ -239,6 +239,52 @@ ccf_config_list(struct cli *cli, const char * const *av, void *priv)
 }
 
 static void
+ccf_config_reload(struct cli *cli, const char * const *av, void *priv)
+{
+	char *oldname;
+	struct vcls *vcl, *vcl_discard;
+	(void)av;
+	(void)priv;
+	ASSERT_CLI();
+
+	asprintf(&oldname, "%s.old", av[2]);
+
+	vcl_discard = vcl_find(oldname);
+	if (vcl_discard) {
+		if (vcl_active == vcl_discard) {
+			cli_out(cli, "VCL named %s exists and is the active VCL.  "
+				"Can not reload %s", oldname, av[2]);
+			free(oldname);
+			return (1);
+		}
+		VSL_stats->n_vcl_discard++;
+		VSL_stats->n_vcl_avail--;
+		vcl_discard->conf->discard = 1;
+		if (vcl_discard->conf->busy == 0)
+			VCL_Nuke(vcl_discard);
+	}
+
+	vcl_discard = vcl_find(av[2]);
+	if (vcl_discard)
+		REPLACE(vcl_discard->name, oldname);
+	free(oldname);
+
+	if (VCL_Load(av[3], av[2], cli)) {
+		cli_result(cli, CLIS_PARAM);
+		REPLACE(vcl_discard->name, av[2]);
+		return (1);
+	}
+	vcl = vcl_find(av[2]);
+
+	Lck_Lock(&vcl_mtx);
+	if (vcl_active == vcl_discard)
+		vcl_active = vcl;
+	Lck_Unlock(&vcl_mtx);
+
+	return;
+}
+
+static void
 ccf_config_load(struct cli *cli, const char * const *av, void *priv)
 {
 
@@ -339,6 +385,7 @@ VCL_##func##_method(struct sess *sp)					\
 
 static struct cli_proto vcl_cmds[] = {
 	{ CLI_VCL_LOAD,         ccf_config_load },
+	{ CLI_VCL_RELOAD,       ccf_config_reload },
 	{ CLI_VCL_LIST,         ccf_config_list },
 	{ CLI_VCL_DISCARD,      ccf_config_discard },
 	{ CLI_VCL_USE,          ccf_config_use },
diff --git a/varnish-cache/bin/varnishd/mgt_cli.c b/varnish-cache/bin/varnishd/mgt_cli.c
index 827cddf..9fc88d7 100644
--- a/varnish-cache/bin/varnishd/mgt_cli.c
+++ b/varnish-cache/bin/varnishd/mgt_cli.c
@@ -135,6 +135,7 @@ static struct cli_proto cli_proto[] = {
 	{ CLI_SERVER_STOP,	mcf_server_startstop, cli_proto },
 	{ CLI_STATS,		mcf_stats, NULL },
 	{ CLI_VCL_LOAD,		mcf_config_load, NULL },
+	{ CLI_VCL_RELOAD,	mcf_config_reload, NULL },
 	{ CLI_VCL_INLINE,	mcf_config_inline, NULL },
 	{ CLI_VCL_USE,		mcf_config_use, NULL },
 	{ CLI_VCL_DISCARD,	mcf_config_discard, NULL },
diff --git a/varnish-cache/bin/varnishd/mgt_cli.h b/varnish-cache/bin/varnishd/mgt_cli.h
index b26dafe..e1e04bf 100644
--- a/varnish-cache/bin/varnishd/mgt_cli.h
+++ b/varnish-cache/bin/varnishd/mgt_cli.h
@@ -39,6 +39,7 @@ cli_func_t mcf_param_set;
 
 /* mgt_vcc.c */
 cli_func_t mcf_config_load;
+cli_func_t mcf_config_reload;
 cli_func_t mcf_config_inline;
 cli_func_t mcf_config_use;
 cli_func_t mcf_config_discard;
diff --git a/varnish-cache/bin/varnishd/mgt_vcc.c b/varnish-cache/bin/varnishd/mgt_vcc.c
index f773f04..cdf0d19 100644
--- a/varnish-cache/bin/varnishd/mgt_vcc.c
+++ b/varnish-cache/bin/varnishd/mgt_vcc.c
@@ -487,6 +487,66 @@ mcf_config_inline(struct cli *cli, const char * const *av, void *priv)
 }
 
 void
+mcf_config_reload(struct cli *cli, const char *const *av, void *priv)
+{
+	char *vf, *vcl, *oldname;
+	struct vsb *sb;
+	unsigned status;
+	char *p = NULL;
+	struct vclprog *vp;
+	int active;
+
+	asprintf(&oldname, "%s.old", av[2]);
+	vp = mgt_vcc_byname(oldname);
+	if (vp != NULL) {
+		if (vp->active) {
+			cli_out(cli, "VCL named %s, is active, can not reload %s",
+				oldname, av[2]);
+			cli_result(cli, CLIS_PARAM);
+			free(oldname);
+			return;
+		}
+		mgt_vcc_del(vp);
+	}
+	vp = mgt_vcc_byname(av[2]);
+
+	vcl = vreadfile(av[3]);
+	if (vcl == NULL) {
+		cli_out(cli, "Cannot open '%s'", av[3]);
+		cli_result(cli, CLIS_PARAM);
+		free(oldname);
+		return;
+	}
+
+	vf = mgt_VccCompile(&sb, vcl, 0);
+	free(vcl);
+
+	if (vsb_len(sb) > 0)
+		cli_out(cli, "%s", vsb_data(sb));
+	vsb_delete(sb);
+	if (vf == NULL) {
+		cli_out(cli, "VCL compilation failed");
+		cli_result(cli, CLIS_PARAM);
+		return;
+	}
+	cli_out(cli, "VCL compiled.");
+
+	if (child_pid >= 0 &&
+	    mgt_cli_askchild(&status, &p, "vcl.reload %s %s\n", av[2], vf)) {
+		cli_result(cli, status);
+		cli_out(cli, "%s", p);
+	} else {
+		active = vp->active;
+		REPLACE(vp->name, oldname);
+		vp->active = 0;
+		vp = mgt_vcc_add(av[2], vf);
+		vp->active = active;
+	}
+	cli_out(cli, "VCL %s reloaded.", av[2]);
+	free(p);
+}
+
+void
 mcf_config_load(struct cli *cli, const char * const *av, void *priv)
 {
 	char *vf, *vcl;
diff --git a/varnish-cache/bin/varnishtest/tests/c00020.vtc b/varnish-cache/bin/varnishtest/tests/c00020.vtc
new file mode 100644
index 0000000..4c3e5ec
--- /dev/null
+++ b/varnish-cache/bin/varnishtest/tests/c00020.vtc
@@ -0,0 +1,15 @@
+# $Id$
+
+test "Check vcl.reload"
+
+shell "echo 'backend b1 { .host = \"localhost\"; }' >/tmp/_varnishtest_c00020.vcl"
+varnish v1 -vcl {
+        backend b { .host = "127.0.0.1"; }
+}
+
+varnish v1 -cli "vcl.reload vcl1 /tmp/_varnishtest_c00020.vcl"
+varnish v1 -start
+varnish v1 -expect n_vcl_avail == 2
+
+varnish v1 -cli "vcl.reload vcl1 /tmp/_varnishtest_c00020.vcl"
+varnish v1 -expect n_vcl_avail == 2
diff --git a/varnish-cache/include/cli.h b/varnish-cache/include/cli.h
index 41b8d10..8cfdf45 100644
--- a/varnish-cache/include/cli.h
+++ b/varnish-cache/include/cli.h
@@ -92,6 +92,12 @@
 	"\tCompile and load the VCL file under the name provided.",	\
 	2, 2
 
+#define CLI_VCL_RELOAD							\
+	"vcl.reload",							\
+	"vcl.reload <configname> <filename>",				\
+	"\tLoad the VCL file under the name provided, discarding the old VCL",	\
+	2, 2
+
 #define CLI_VCL_INLINE							\
 	"vcl.inline",							\
 	"vcl.inline <configname> <quoted_VCLstring>",			\
diff --git a/varnish-cache/lib/libvcl/vcc_fixed_token.c b/varnish-cache/lib/libvcl/vcc_fixed_token.c
index a94c7fc..abfb944 100644
