diff --git a/src/wp-includes/js/customize-base.js b/src/wp-includes/js/customize-base.js
index a1528de4f..94dc25c6e 100644
--- a/src/wp-includes/js/customize-base.js
+++ b/src/wp-includes/js/customize-base.js
@@ -203,12 +203,14 @@ window.wp = window.wp || {};
 		 * Set the value and trigger all bound callbacks.
 		 *
 		 * @param {object} to New value.
+     * @param {object} set of optional arguments when setting the value
 		 */
-		set: function( to ) {
-			var from = this._value;
+		set: function( to, args ) {
+			var from = this._value, self = this;
 
 			to = this._setter.apply( this, arguments );
 			to = this.validate( to );
+			args = _.extend( { silent : false }, _.isObject( args ) ? args : {} );
 
 			// Bail if the sanitized value is null or unchanged.
 			if ( null === to || _.isEqual( from, to ) ) {
@@ -217,8 +219,16 @@ window.wp = window.wp || {};
 
 			this._value = to;
 			this._dirty = true;
+			if ( args.silent ) {
+			  return this;
+			}
 
 			this.callbacks.fireWith( this, [ to, from ] );
+			if ( this.topics ) {
+			  _.each( self.topics, function( _cbs ){
+						_cbs.fireWith( self, [ to, from ] );
+			  });
+			}
 
 			return this;
 		},
@@ -247,22 +257,68 @@ window.wp = window.wp || {};
 		},
 
 		/**
-		 * Bind a function to be invoked whenever the value changes.
+		 * Trigger the bound callbacks of a specific topic, or trigger the anonymous callbacks
 		 *
+		 * @param {string} the topic id
+		 * @param {to} the optional new value
+		 * @param {from} the optional previous value
+		 */
+		trigger: function( id, to, from ) {
+			to = to || this();
+			from = from || this();
+			if ( this.topics && this.topics[ id ] ) {
+			  this.topics[ id ].fireWith( this, [ to, from ] );
+			} else {
+			  this.callbacks.fireWith( this, [ to, from ] );
+			}
+			return this;
+		},
+
+		/**
+		 * Bind a function to be invoked whenever the value changes.
+		 * @param {string} the optional id of the callbacks topic
 		 * @param {...Function} A function, or multiple functions, to add to the callback stack.
 		 */
-		bind: function() {
-			this.callbacks.add.apply( this.callbacks, arguments );
+		bind: function( id ) {
+			if ( _.isFunction( id ) ) {
+			  this.callbacks.add.apply( this.callbacks, arguments );
+			} else {
+			  this.topics = this.topics || {};
+			  this.topics[ id ] = this.topics[ id ] || $.Callbacks();
+			  this.topics[ id ].add.apply( this.topics[ id ], slice.call( arguments, 1 ) );
+			}
 			return this;
 		},
 
 		/**
 		 * Unbind a previously bound function.
 		 *
+		 * @param {string} the optional id of the callbacks topic
 		 * @param {...Function} A function, or multiple functions, to remove from the callback stack.
 		 */
-		unbind: function() {
-			this.callbacks.remove.apply( this.callbacks, arguments );
+		unbind: function( id ) {
+			if ( _.isFunction( id ) ) {
+			  this.callbacks.remove.apply( this.callbacks, arguments );
+			} else if ( this.topics && this.topics[ id ] ) {
+			  this.topics[ id ].remove.apply( this.topics[ id ], slice.call( arguments, 1 ) );
+			}
+			return this;
+		},
+
+		/**
+		 * Unbind all previously bound function of a callbacks topic if specified
+		 * Or unbind all functions if no topic is specified
+		 *
+		 * @param {string} optional topic id
+		 */
+		unbindAll: function( id ) {
+			if ( this.topics && this.topics[ id ] ) {
+			  this.topics[ id ] = $.Callbacks();
+			} else if ( this.topics ) {
+			  this.topics = {};
+			} else {
+			  this.callbacks = $.Callbacks();
+			}
 			return this;
 		},
 
