Index: src/wp-includes/class-wp-rewrite.php
===================================================================
--- src/wp-includes/class-wp-rewrite.php	(revision 34653)
+++ src/wp-includes/class-wp-rewrite.php	(working copy)
@@ -1510,24 +1510,33 @@
 	 * the top of the rules.
 	 *
 	 * @since 2.1.0
+	 * @since 4.4.0 Array support was added to the `$redirect` parameter.
 	 * @access public
 	 *
-	 * @param string $regex    Regular expression to match against request.
-	 * @param string $redirect URL regex redirects to when regex matches request.
-	 * @param string $after    Optional, default is bottom. Location to place rule.
+	 * @param string       $regex    Regular expression to match against request.
+	 * @param string|array $redirect URL regex redirects to when regex matches request, or array
+	 *                               of query vars and values.
+	 * @param string       $after    Optional, default is bottom. Location to place rule.
 	 */
-	public function add_rule($regex, $redirect, $after = 'bottom') {
-		//get everything up to the first ?
-		$index = (strpos($redirect, '?') === false ? strlen($redirect) : strpos($redirect, '?'));
-		$front = substr($redirect, 0, $index);
-		if ( $front != $this->index ) { //it doesn't redirect to WP's index.php
-			$this->add_external_rule($regex, $redirect);
+	public function add_rule( $regex, $redirect, $after = 'bottom' ) {
+		if ( is_array( $redirect ) ) {
+			$external = false;
+			$redirect = add_query_arg( $redirect, 'index.php' );
 		} else {
+			$index = false === strpos( $redirect, '?' ) ? strlen( $redirect ) : strpos( $redirect, '?' );
+			$front = substr( $redirect, 0, $index );
+
+			$external = $front != $this->index;
+		}
+
+		// "external" = it doesn't redirect to index.php
+		if ( $external ) {
+			$this->add_external_rule( $regex, $redirect );
+		} else {
 			if ( 'bottom' == $after)
 				$this->extra_rules = array_merge($this->extra_rules, array($regex => $redirect));
 			else
 				$this->extra_rules_top = array_merge($this->extra_rules_top, array($regex => $redirect));
-			//$this->extra_rules[$regex] = $redirect;
 		}
 	}
 
Index: src/wp-includes/rewrite-functions.php
===================================================================
--- src/wp-includes/rewrite-functions.php	(revision 34653)
+++ src/wp-includes/rewrite-functions.php	(working copy)
@@ -7,19 +7,21 @@
  */
 
 /**
- * Add a straight rewrite rule.
+ * Adds a straight rewrite rule.
  *
  * @since 2.1.0
+ * @since 4.4.0 Array support was added to the `$redirect` parameter.
  *
- * @global WP_Rewrite $wp_rewrite
+ * @global WP_Rewrite $wp_rewrite WordPress Rewrite Component.
  *
- * @param string $regex    Regular Expression to match request against.
- * @param string $redirect Page to redirect to.
- * @param string $after    Optional, default is 'bottom'. Where to add rule, can also be 'top'.
+ * @param string       $regex    Regular Expression to match request against.
+ * @param string|array $redirect Page to redirect to, or array of query vars and values.
+ * @param string       $after    Optional, default is 'bottom'. Where to add rule, can also be 'top'.
  */
-function add_rewrite_rule($regex, $redirect, $after = 'bottom') {
+function add_rewrite_rule( $regex, $redirect, $after = 'bottom' ) {
 	global $wp_rewrite;
-	$wp_rewrite->add_rule($regex, $redirect, $after);
+
+	$wp_rewrite->add_rule( $regex, $redirect, $after );
 }
 
 /**
Index: tests/phpunit/tests/rewrite/addRewriteRule.php
===================================================================
--- tests/phpunit/tests/rewrite/addRewriteRule.php	(revision 0)
+++ tests/phpunit/tests/rewrite/addRewriteRule.php	(working copy)
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * @group rewrite
+ */
+class Tests_Rewrite_AddRewriteRule extends WP_UnitTestCase {
+
+
+	public function setUp() {
+		global $wp_rewrite;
+		parent::setUp();
+
+		$wp_rewrite->init();
+		$wp_rewrite->set_permalink_structure( '/%postname%/' );
+		$wp_rewrite->flush_rules();
+	}
+
+	public function tearDown() {
+		global $wp_rewrite;
+		$wp_rewrite->init();
+
+		parent::tearDown();
+	}
+
+	/**
+	 * @ticket 16840
+	 */
+	public function test_add_rewrite_rule_redirect() {
+		global $wp_rewrite;
+
+		$pattern  = 'path/to/rewrite/([^/]+)/?$';
+		$redirect = 'index.php?test_var1=$matches[1]&test_var2=1';
+		add_rewrite_rule( $pattern, $redirect );
+
+		flush_rewrite_rules();
+
+		$this->assertContains( $redirect, $wp_rewrite->rewrite_rules() );
+	}
+
+	/**
+	 * @ticket 16840
+	 */
+	public function test_add_rewrite_rule_redirect_array() {
+		global $wp_rewrite;
+
+		$pattern  = 'path/to/rewrite/([^/]+)/?$';
+		$redirect = 'index.php?test_var1=$matches[1]&test_var2=1';
+
+		add_rewrite_rule( $pattern, array(
+			'test_var1' => '$matches[1]',
+			'test_var2' => '1'
+		) );
+
+		flush_rewrite_rules();
+
+		$this->assertContains( $redirect, $wp_rewrite->rewrite_rules() );
+	}
+}
Index: tests/phpunit/tests/rewrite.php
===================================================================
--- tests/phpunit/tests/rewrite.php	(revision 34653)
+++ tests/phpunit/tests/rewrite.php	(working copy)
@@ -31,6 +31,57 @@
 		parent::tearDown();
 	}
 
+	/**
+	 * @ticket 16840
+	 */
+	public function test_add_rule() {
+		global $wp_rewrite;
+
+		$pattern  = 'path/to/rewrite/([^/]+)/?$';
+		$redirect = 'index.php?test_var1=$matches[1]&test_var2=1';
+
+		$wp_rewrite->add_rule( $pattern, $redirect );
+
+		$wp_rewrite->flush_rules();
+
+		$this->assertContains( $redirect, $wp_rewrite->rewrite_rules() );
+	}
+
+	/**
+	 * @ticket 16840
+	 */
+	public function test_add_rule_redirect_array() {
+		global $wp_rewrite;
+
+		$pattern  = 'path/to/rewrite/([^/]+)/?$';
+		$redirect = 'index.php?test_var1=$matches[1]&test_var2=1';
+
+		$wp_rewrite->add_rule( $pattern, array(
+			'test_var1' => '$matches[1]',
+			'test_var2' => '1'
+		) );
+
+		$wp_rewrite->flush_rules();
+
+		$this->assertContains( $redirect, $wp_rewrite->rewrite_rules() );
+	}
+
+	/**
+	 * @ticket 16840
+	 */
+	public function test_add_rule_top() {
+		global $wp_rewrite;
+
+		$pattern  = 'path/to/rewrite/([^/]+)/?$';
+		$redirect = 'index.php?test_var1=$matches[1]&test_var2=1';
+
+		$wp_rewrite->add_rule( $pattern, $redirect, 'top' );
+
+		$wp_rewrite->flush_rules();
+
+		$this->assertContains( $redirect, $wp_rewrite->extra_rules_top );
+	}
+
 	function test_url_to_postid() {
 
 		$id = $this->factory->post->create();
