diff --git src/wp-includes/class.wp-scripts.php src/wp-includes/class.wp-scripts.php
index 81634ec..e718f82 100644
--- src/wp-includes/class.wp-scripts.php
+++ src/wp-includes/class.wp-scripts.php
@@ -461,6 +461,94 @@ class WP_Scripts extends WP_Dependencies {
 	}
 
 	/**
+	 * Pass data to a script if the script has already been added.
+	 *
+	 * @since 4.8.0
+	 * @access public
+	 *
+	 * @param string $handle
+	 * @param string $object_name
+	 * @param array $data
+	 * @return bool
+	 */
+	public function pass_data( $handle, $object_name, $data ) {
+
+		// Pass scalar values untouched; pass strings through html_entity_decode.
+		if ( is_scalar( $data ) ) {
+
+			// Pass strings through html_entity_decode, pass other scalar untouched.
+			if ( is_string( $data ) ) {
+				$data = html_entity_decode( $data, ENT_QUOTES, 'UTF-8');
+			}
+		} else {
+			// Recurse over passed arrays. Cast objects to arrays.
+			foreach ( (array) $data as $key => $value ) {
+
+				// Pass scalar values untouched; pass strings through html_entity_decode.
+				if ( is_scalar( $value ) ) {
+
+					// Pass strings through html_entity_decode, pass other scalar values untouched.
+					if ( is_string( $value ) ) {
+						$data[ $key ] = html_entity_decode( $value, ENT_QUOTES, 'UTF-8');
+					} else {
+						$data[$key] = $value;
+					}
+				} else {
+
+					$data = $this->entity_decode_array_values( $data );
+				}
+			}
+		}
+
+		$script = "var $object_name = " . wp_json_encode( $data ) . ';';
+
+		if ( ! empty( $after ) )
+			$script .= "\n$after;";
+
+		$data = $this->get_data( $handle, 'data' );
+
+		if ( ! empty( $data ) )
+			$script = "$data\n$script";
+
+		return $this->add_data( $handle, 'data', $script );
+	}
+
+	/**
+	* Handles recursively HTML entity decoding multi-dimensional array values.
+	*
+	* @since 4.8.0
+	*
+	* @param  array $data_array Array of data which should be decoded.
+	*
+	* @return array Array with decoded values.
+	*/
+	public function entity_decode_array_values( $data_array ) {
+
+		// Begin a new array so that non-decoded values do not get added.
+		$data = array();
+
+		foreach ( (array) $data_array as $key => $value ) {
+			if ( is_array( $value ) ) {
+				$data[ $key ] = $this->entity_decode_array_values( $value );
+			}
+
+			// Non-array, non-scalar values should not be added.
+			if ( ! is_scalar( $value ) ) {
+				continue;
+			}
+
+			// Pass strings through html_entity_decode, pass other scalar untouched.
+			if ( is_string( $value ) ) {
+				$data[ $key ] = html_entity_decode( $value, ENT_QUOTES, 'UTF-8');
+			} else {
+				$data[ $key ] = $value;
+			}
+		}
+
+		return $data;
+	}
+
+	/**
 	 * Sets handle group.
 	 *
 	 * @since 2.8.0
diff --git src/wp-includes/functions.wp-scripts.php src/wp-includes/functions.wp-scripts.php
index dccaaf2..50ae172 100644
--- src/wp-includes/functions.wp-scripts.php
+++ src/wp-includes/functions.wp-scripts.php
@@ -193,6 +193,29 @@ function wp_localize_script( $handle, $object_name, $l10n ) {
 }
 
 /**
+ * Pass data from PHP to a registered JavaScript file.
+ *
+ * Accepts a scalar value or and associative array and creates a JavaScript object.
+ *
+ * @since 4.8.0
+ *
+ * @param string $handle      Script handle the data will be attached to.
+ * @param string $object_name Name for the JavaScript object. Passed directly, so it should be qualified JS variable.
+ * @param array  $data        The data itself. The data can be either a scalar value, or a single or multi-dimensional array.
+ *
+ * @return bool True if the script was successfully localized, false otherwise.
+ */
+function wp_pass_data_to_script( $handle, $object_name, $data ) {
+	global $wp_scripts;
+	if ( ! ( $wp_scripts instanceof WP_Scripts ) ) {
+		_wp_scripts_maybe_doing_it_wrong( __FUNCTION__ );
+		return false;
+	}
+
+	return $wp_scripts->pass_data( $handle, $object_name, $data );
+}
+
+/**
  * Remove a registered script.
  *
  * Note: there are intentional safeguards in place to prevent critical admin scripts,
diff --git tests/phpunit/tests/dependencies/scripts.php tests/phpunit/tests/dependencies/scripts.php
index efe5a7b..6b21281 100644
--- tests/phpunit/tests/dependencies/scripts.php
+++ tests/phpunit/tests/dependencies/scripts.php
@@ -724,4 +724,63 @@ class Tests_Dependencies_Scripts extends WP_UnitTestCase {
 
 		$this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
 	}
+
+	/**
+	 * Testing `wp_pass_data_to_script` with scalar and array values.
+	 * @ticket 25280
+	 */
+	function test_wp_pass_data_to_script_with_scalar_and_multidimensional_arrays() {
+		// Enqueue & localize variables
+		wp_enqueue_script( 'test-l10n-data', 'example.com', array(), null );
+		wp_pass_data_to_script( 'test-l10n-data', 'data', true );
+
+		$test_array = array( 'var' => 'string' );
+		wp_pass_data_to_script( 'test-l10n-data', 'dataArray', $test_array );
+
+		$test_multidimensional = array(
+			'first-level' => array(
+				'second-level' => array(
+					'index' => "I'll \"walk\" the <b>dog</b> now",
+				),
+			),
+		);
+		wp_pass_data_to_script( 'test-l10n-data', 'dataMultiDimensionalArray', $test_multidimensional );
+
+
+		// Boolean output.
+		$expected = "var data = true;\n";
+		// One-dimensional array output.
+		$expected .= "var dataArray = {\"var\":\"string\"};\n";
+		// Multi-dimensional array output with odd characters.
+		$string = '\"walk\"';
+		$expected .= "var dataMultiDimensionalArray = {\"first-level\":{\"second-level\":{\"index\":\"I'll " .
+			$string . " the <b>dog<\/b> now\"}}};\n";
+		// var script wrapper output
+		$expected = "<script type='text/javascript'>\n/* <![CDATA[ */\n$expected/* ]]> */\n</script>\n";
+		// script link output
+		$expected .= "<script type='text/javascript' src='http://example.com'></script>\n";
+		$this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
+		// No scripts left to print
+		$this->assertEquals( '', get_echo( 'wp_print_scripts' ) );
+	}
+
+	/**
+	 * Test passing data to scripts via `wp_pass_data_to_script`.
+	 *
+	 * @ticket 25280
+	 */
+	function test_wp_pass_data_to_script_doesnt_convert_types_unexpectedly() {
+		global $wp_scripts;
+		$array_to_pass = array(
+			'a_string'  => __( 'Some String' ),
+			'a_number'  => 10,
+			'a_boolean' => true,
+		);
+		wp_enqueue_script( 'localize_test','localize_script.js', array(), '1.0.0', true );
+		wp_pass_data_to_script( 'localize_test', 'localized_variable', $array_to_pass );
+		$this->assertEquals(
+			'var localized_variable = {"a_string":"Some String","a_number":10,"a_boolean":true};',
+			$wp_scripts->print_extra_script( 'localize_test', false )
+		);
+	}
 }
