diff --git a/lib/cli.py b/lib/cli.py
index ca3e299856dda9ba478abf5702136e7bd187f07a..a5d3a80b4dab952ef46ee13dd0da56147dbde1b0 100644
--- a/lib/cli.py
+++ b/lib/cli.py
@@ -44,9 +44,9 @@ __all__ = ["DEBUG_OPT", "NOHDR_OPT", "SEP_OPT", "GenericMain",
            "SubmitOpCode", "GetClient",
            "cli_option", "GenerateTable", "AskUser",
            "ARGS_NONE", "ARGS_FIXED", "ARGS_ATLEAST", "ARGS_ANY", "ARGS_ONE",
-           "USEUNITS_OPT", "FIELDS_OPT", "FORCE_OPT",
+           "USEUNITS_OPT", "FIELDS_OPT", "FORCE_OPT", "SUBMIT_OPT",
            "ListTags", "AddTags", "RemoveTags", "TAG_SRC_OPT",
-           "FormatError", "SplitNodeOption"
+           "FormatError", "SplitNodeOption", "SubmitOrSend",
            ]
 
 
@@ -180,6 +180,11 @@ FORCE_OPT = make_option("-f", "--force", dest="force", action="store_true",
 TAG_SRC_OPT = make_option("--from", dest="tags_source",
                           default=None, help="File with tag names")
 
+SUBMIT_OPT = make_option("--submit", dest="submit_only",
+                         default=False, action="store_true",
+                         help="Submit the job and return the job ID, but"
+                         " don't wait for the job to finish")
+
 
 def ARGS_FIXED(val):
   """Macro-like function denoting a fixed number of arguments"""
@@ -447,6 +452,22 @@ def SubmitOpCode(op, cl=None, feedback_fn=None):
   return PollJob(job_id, cl)
 
 
+def SubmitOrSend(op, opts, cl=None, feedback_fn=None):
+  """Wrapper around SubmitOpCode or SendJob.
+
+  This function will decide, based on the 'opts' parameter, whether to
+  submit and wait for the result of the opcode (and return it), or
+  whether to just send the job and print its identifier. It is used in
+  order to simplify the implementation of the '--submit' option.
+
+  """
+  if opts and opts.submit_only:
+    print SendJob([op], cl=cl)
+    sys.exit(0)
+  else:
+    return SubmitOpCode(op, cl=cl, feedback_fn=feedback_fn)
+
+
 def GetClient():
   # TODO: Cache object?
   try:
diff --git a/scripts/gnt-node b/scripts/gnt-node
index dc988ccb89f15179b2805d6ad847ecc9c4c2e115..c75737f5dcdcc95921312ec03bfa765c3ec7c0ed 100755
--- a/scripts/gnt-node
+++ b/scripts/gnt-node
@@ -79,7 +79,7 @@ def ListNodes(opts, args):
     selected_fields = opts.output.split(",")
 
   op = opcodes.OpQueryNodes(output_fields=selected_fields, names=[])
-  output = SubmitOpCode(op)
+  output = SubmitOrSend(op, opts)
 
   if not opts.no_headers:
     headers = {
@@ -335,7 +335,8 @@ commands = {
   'info': (ShowNodeConfig, ARGS_ANY, [DEBUG_OPT],
            "[<node_name>...]", "Show information about the node(s)"),
   'list': (ListNodes, ARGS_NONE,
-           [DEBUG_OPT, NOHDR_OPT, SEP_OPT, USEUNITS_OPT, FIELDS_OPT],
+           [DEBUG_OPT, NOHDR_OPT, SEP_OPT, USEUNITS_OPT, FIELDS_OPT,
+            SUBMIT_OPT],
            "", "Lists the nodes in the cluster. The available fields"
            " are (see the man page for details): name, pinst_cnt, pinst_list,"
            " sinst_cnt, sinst_list, pip, sip, dtotal, dfree, mtotal, mnode,"