diff --git a/tools/virsh.c b/tools/virsh.c
index 363bf419cc..d1ebc4093a 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -11996,15 +11996,45 @@ vshSnapshotCreate(vshControl *ctl, virDomainPtr dom, const char *buffer,
 {
     bool ret = false;
     virDomainSnapshotPtr snapshot;
+    bool halt = false;
     char *doc = NULL;
     xmlDocPtr xml = NULL;
     xmlXPathContextPtr ctxt = NULL;
     char *name = NULL;
 
     snapshot = virDomainSnapshotCreateXML(dom, buffer, flags);
+
+    /* Emulate --halt on older servers.  */
+    if (!snapshot && last_error->code == VIR_ERR_INVALID_ARG &&
+        (flags & VIR_DOMAIN_SNAPSHOT_CREATE_HALT)) {
+        int persistent;
+
+        virFreeError(last_error);
+        last_error = NULL;
+        persistent = virDomainIsPersistent(dom);
+        if (persistent < 0) {
+            virshReportError(ctl);
+            goto cleanup;
+        }
+        if (!persistent) {
+            vshError(ctl, "%s",
+                     _("cannot halt after snapshot of transient domain"));
+            goto cleanup;
+        }
+        if (virDomainIsActive(dom) == 1)
+            halt = true;
+        flags &= ~VIR_DOMAIN_SNAPSHOT_CREATE_HALT;
+        snapshot = virDomainSnapshotCreateXML(dom, buffer, flags);
+    }
+
     if (snapshot == NULL)
         goto cleanup;
 
+    if (halt && virDomainDestroy(dom) < 0) {
+        virshReportError(ctl);
+        goto cleanup;
+    }
+
     if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)
         doc = vshStrdup(ctl, buffer);
     else
@@ -12055,6 +12085,7 @@ static const vshCmdOptDef opts_snapshot_create[] = {
     {"redefine", VSH_OT_BOOL, 0, N_("redefine metadata for existing snapshot")},
     {"current", VSH_OT_BOOL, 0, N_("with redefine, set current snapshot")},
     {"no-metadata", VSH_OT_BOOL, 0, N_("take snapshot but create no metadata")},
+    {"halt", VSH_OT_BOOL, 0, N_("halt domain after snapshot is created")},
     {NULL, 0, 0, NULL}
 };
 
@@ -12073,6 +12104,8 @@ cmdSnapshotCreate(vshControl *ctl, const vshCmd *cmd)
         flags |= VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT;
     if (vshCommandOptBool(cmd, "no-metadata"))
         flags |= VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA;
+    if (vshCommandOptBool(cmd, "halt"))
+        flags |= VIR_DOMAIN_SNAPSHOT_CREATE_HALT;
 
     if (!vshConnectionUsability(ctl, ctl->conn))
         goto cleanup;
@@ -12123,6 +12156,7 @@ static const vshCmdOptDef opts_snapshot_create_as[] = {
     {"description", VSH_OT_DATA, 0, N_("description of snapshot")},
     {"print-xml", VSH_OT_BOOL, 0, N_("print XML document rather than create")},
     {"no-metadata", VSH_OT_BOOL, 0, N_("take snapshot but create no metadata")},
+    {"halt", VSH_OT_BOOL, 0, N_("halt domain after snapshot is created")},
     {NULL, 0, 0, NULL}
 };
 
@@ -12139,6 +12173,8 @@ cmdSnapshotCreateAs(vshControl *ctl, const vshCmd *cmd)
 
     if (vshCommandOptBool(cmd, "no-metadata"))
         flags |= VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA;
+    if (vshCommandOptBool(cmd, "halt"))
+        flags |= VIR_DOMAIN_SNAPSHOT_CREATE_HALT;
 
     if (!vshConnectionUsability(ctl, ctl->conn))
         goto cleanup;
@@ -12167,6 +12203,11 @@ cmdSnapshotCreateAs(vshControl *ctl, const vshCmd *cmd)
     }
 
     if (vshCommandOptBool(cmd, "print-xml")) {
+        if (vshCommandOptBool(cmd, "halt")) {
+            vshError(ctl, "%s",
+                     _("--print-xml and --halt are mutually exclusive"));
+            goto cleanup;
+        }
         vshPrint(ctl, "%s\n",  buffer);
         ret = true;
         goto cleanup;
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 3557a0d859..8edf30efdd 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1702,7 +1702,7 @@ used to represent properties of snapshots.
 =over 4
 
 =item B<snapshot-create> I<domain> [I<xmlfile>] {[I<--redefine> [I<--current>]]
-| [I<--no-metadata>]}
+| [I<--no-metadata>] [I<--halt>]}
 
 Create a snapshot for domain I<domain> with the properties specified in
 I<xmlfile>.  Normally, the only properties settable for a domain snapshot
@@ -1711,6 +1711,9 @@ ignored, and automatically filled in by libvirt.  If I<xmlfile> is
 completely omitted, then libvirt will choose a value for all fields.
 The new snapshot will become current, as listed by B<snapshot-current>.
 
+If I<--halt> is specified, the domain will be left in an inactive state
+after the snapshot is created.
+
 If I<--redefine> is specified, then all XML elements produced by
 B<snapshot-dumpxml> are valid; this can be used to migrate snapshot
 hierarchy from one machine to another, to recreate hierarchy for the
@@ -1732,13 +1735,15 @@ a persistent domain.  However, for transient domains, snapshot
 metadata is silently lost when the domain quits running (whether
 by command such as B<destroy> or by internal guest action).
 
-=item B<snapshot-create-as> I<domain> {[I<--print-xml>] | [I<--no-metadata>]}
-[I<name>] [I<description>]
+=item B<snapshot-create-as> I<domain> {[I<--print-xml>]
+| [I<--no-metadata>] [I<--halt>]} [I<name>] [I<description>]
 
 Create a snapshot for domain I<domain> with the given <name> and
 <description>; if either value is omitted, libvirt will choose a
 value.  If I<--print-xml> is specified, then XML appropriate for
 I<snapshot-create> is output, rather than actually creating a snapshot.
+Otherwise, if I<--halt> is specified, the domain will be left in an
+inactive state after the snapshot is created.
 
 If I<--no-metadata> is specified, then the snapshot data is created,
 but any metadata is immediately discarded (that is, libvirt does not