diff --git a/doc/tar.texi b/doc/tar.texi
index fe09c12..1cc8a8a 100644
--- a/doc/tar.texi
+++ b/doc/tar.texi
@@ -2606,6 +2606,13 @@ widely used version control systems.
 
 @xref{exclude}.
 
+@opsummary{export-headers}
+@item --export-headers
+@itemx -Q
+
+During extraction with @option{--to-stdout} (@option{-O}), the extracted files'
+headers will also be written.  @xref{Writing to Standard Output}.
+
 @opsummary{file}
 @item --file=@var{archive}
 @itemx -f @var{archive}
@@ -3398,6 +3405,8 @@ them with the equivalent long option.
 
 @item -P @tab @ref{--absolute-names}.
 
+@item -Q @tab @ref{--export-headers}.
+
 @item -R @tab @ref{--block-number}.
 
 @item -S @tab @ref{--sparse}.
@@ -5118,7 +5127,9 @@ conjunction with @option{--extract} (@option{--get}, @option{-x}).  This option
 extracting files to send them through a pipe, and do not need to
 preserve them in the file system.  If you extract multiple members,
 they appear on standard output concatenated, in the order they are
-found in the archive.
+found in the archive.  Alternatively, the @option{--export-headers}
+(@option{-Q}) modifier will preserve archive information so a subset of the
+archive can be piped to another program.
 
 @table @option
 @opindex to-stdout
@@ -5150,6 +5161,23 @@ tar -xOzf foo.tgz bigfile1 bigfile2 | process
 However, @option{--to-command} may be more convenient for use with
 multiple files. See the next section.
 
+@table @option
+@opindex export-headers
+@item --export-headers
+@itemx -Q
+Writes the headers of extracted files when using @option{--get} (@option{-x})
+with @option{--to-stdout} (@option{-O}) or @option{--to-command}.
+@end table
+
+This is meant to be used in conjunction with a list of files to be extracted.
+The extracted files are left in archive format, thereby creating a subset of the
+input archive.  This can be especially useful for extracting part of an archive
+across a network. For example:
+
+@smallexample
+tar -xOQf foo.tar file1 file2 | ssh user@@server tar -x
+@end smallexample
+
 @node Writing to an External Program
 @unnumberedsubsubsec Writing to an External Program
 
diff --git a/src/common.h b/src/common.h
index 9897b46..05779e1 100644
--- a/src/common.h
+++ b/src/common.h
@@ -264,6 +264,7 @@ GLOBAL bool starting_file_option;
 GLOBAL tarlong tape_length_option;
 
 GLOBAL bool to_stdout_option;
+GLOBAL bool export_headers_option;
 
 GLOBAL bool totals_option;
 
diff --git a/src/create.c b/src/create.c
index a925160..c605fb4 100644
diff --git a/src/extract.c b/src/extract.c
index 63f3525..e393547 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -809,6 +809,11 @@ extract_file (char *file_name, int typeflag)
     }
 
   mv_begin (&current_stat_info);
+
+  /*(normally taken care of in prepare_to_extract)*/
+  if (to_command_option && export_headers_option)
+  write(fd, &current_header->buffer, sizeof current_header->buffer);
+
   if (current_stat_info.is_sparse)
     sparse_extract_file (fd, &current_stat_info, &size);
   else
@@ -846,6 +851,19 @@ extract_file (char *file_name, int typeflag)
 	  }
       }
 
+  /*pad output if headers were exported to retain archive format*/
+  if (export_headers_option)
+    {
+      int to_pad = current_stat_info.archive_file_size % BLOCKSIZE;
+      if (to_pad)
+        {
+          to_pad = BLOCKSIZE - to_pad;
+          char *zero_padding = calloc(1, to_pad);
+          write(fd, zero_padding, to_pad);
+          free(zero_padding);
+        }
+    }
+
   skip_file (size);
 
   mv_end ();
@@ -1108,7 +1126,7 @@ typedef int (*tar_extractor_t) (char *file_name, int typeflag);
 static int
 prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
 {
-  int rc = 1;
+  int rc = 1, fd = -1;
 
   if (EXTRACT_OVER_PIPE)
     rc = 0;
@@ -1194,6 +1212,26 @@ prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
       *fun = extract_file;
     }
 
+  /*send the header to output if applicable*/
+  if (EXTRACT_OVER_PIPE && export_headers_option && *fun != &extract_failure)
+    {
+      if (to_stdout_option)
+        fd = STDOUT_FILENO;
+      else if (to_command_option && !rc)
+        {
+          char *file_name2 = strdup(file_name);
+          fd = sys_exec_command (file_name2, 'f', &current_stat_info);
+          free(file_name2);
+          if (fd < 0) return 0;
+        }
+
+      if (fd != -1)
+        {
+          write(fd, &current_header->buffer, sizeof current_header->buffer);
+          if (to_command_option) close(fd);
+        }
+    }
+
   /* Determine whether the extraction should proceed */
   if (rc == 0)
     return 0;
diff --git a/src/tar.c b/src/tar.c
index 31537eb..f7d9e5e 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -454,6 +454,8 @@ static struct argp_option options[] = {
 
   {"to-stdout", 'O', 0, 0,
    N_("extract files to standard output"), GRID+1 },
+  {"export-headers", 'Q', 0, 0,
+   N_("extract files and tar headers to standard output"), GRID+1 },
   {"to-command", TO_COMMAND_OPTION, N_("COMMAND"), 0,
    N_("pipe extracted files to another program"), GRID+1 },
   {"ignore-command-error", IGNORE_COMMAND_ERROR_OPTION, 0, 0,
@@ -1453,6 +1455,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
       to_stdout_option = true;
       break;
 
+    case 'Q':
+      export_headers_option = true;
+      break;
+
     case 'p':
       same_permissions_option = true;
       break;
@@ -2335,6 +2341,14 @@ decode_options (int argc, char **argv)
   if (recursive_unlink_option)
     old_files_option = UNLINK_FIRST_OLD_FILES;
 
+  if (export_headers_option)
+    {
+      if (subcommand_option != EXTRACT_SUBCOMMAND)
+	USAGE_ERROR ((0, 0, _("Can only export headers with extraction")));
+      if (!EXTRACT_OVER_PIPE)
+	USAGE_ERROR ((0, 0, _("Cannot export headers to file system")));
+    }
+
 
   if (test_label_option)
     {
