diff --git src/wp-admin/options-general.php src/wp-admin/options-general.php
index 220b07e..d4e7250 100644
--- src/wp-admin/options-general.php
+++ src/wp-admin/options-general.php
@@ -73,7 +73,7 @@ include( ABSPATH . 'wp-admin/admin-header.php' );
 <tr>
 <th scope="row"><label for="home"><?php _e('Site Address (URL)') ?></label></th>
 <td><input name="home" type="url" id="home" aria-describedby="home-description" value="<?php form_option( 'home' ); ?>"<?php disabled( defined( 'WP_HOME' ) ); ?> class="regular-text code<?php if ( defined( 'WP_HOME' ) ) echo ' disabled' ?>" />
-<?php if ( ! defined( 'WP_HOME' ) ) : ?> 
+<?php if ( ! defined( 'WP_HOME' ) ) : ?>
 <p class="description" id="home-description"><?php _e( 'Enter the address here if you <a href="https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory">want your site home page to be different from your WordPress installation directory.</a>' ); ?></p></td>
 <?php endif; ?>
 </tr>
@@ -90,6 +90,28 @@ include( ABSPATH . 'wp-admin/admin-header.php' );
 </fieldset></td>
 </tr>
 <tr>
+<th scope="row"><?php _e( 'Limited Email Registrations' ) ?></th>
+<td> <fieldset><legend class="screen-reader-text"><span><?php _e( 'Limited Email Registrations' ) ?></span></legend>
+<p><label for="limited_email_domains"><?php _e( 'If you want to limit site registrations to certain domains. One domain per line.' ) ?></label></p>
+<?php $limited_email_domains = get_option( 'limited_email_domains' );
+$limited_email_domains = str_replace( ' ', "\n", $limited_email_domains ); ?>
+<p>
+<textarea name="limited_email_domains" id="limited_email_domains" cols="45" rows="5" class="large-text code"><?php echo esc_textarea( $limited_email_domains == '' ? '' : implode( "\n", (array) $limited_email_domains ) ); ?></textarea>
+</p>
+</fieldset></td>
+</tr>
+<tr>
+<th scope="row"><?php _e( 'Banned Email Domains' ) ?></th>
+<td> <fieldset><legend class="screen-reader-text"><span><?php _e( 'Banned Email Domains' ) ?></span></legend>
+<p><label for="banned_email_domains"><?php _e( 'If you want to ban domains from site registrations. One domain per line.' ) ?></label></p>
+<?php $banned_email_domains = get_option( 'banned_email_domains' );
+$banned_email_domains = str_replace( ' ', "\n", $banned_email_domains ); ?>
+<p>
+<textarea name="banned_email_domains" id="banned_email_domains" cols="45" rows="5" class="large-text code"><?php echo esc_textarea( $banned_email_domains == '' ? '' : implode( "\n", (array) $banned_email_domains ) ); ?></textarea>
+</p>
+</fieldset></td>
+</tr>
+<tr>
 <th scope="row"><label for="default_role"><?php _e('New User Default Role') ?></label></th>
 <td>
 <select name="default_role" id="default_role"><?php wp_dropdown_roles( get_option('default_role') ); ?></select>
diff --git src/wp-admin/options.php src/wp-admin/options.php
index e2bfa90..8bd1bc4 100644
--- src/wp-admin/options.php
+++ src/wp-admin/options.php
@@ -108,6 +108,8 @@ if ( !is_multisite() ) {
 
 	$whitelist_options['general'][] = 'admin_email';
 	$whitelist_options['general'][] = 'users_can_register';
+	$whitelist_options['general'][] = 'limited_email_domains';
+	$whitelist_options['general'][] = 'banned_email_domains';
 	$whitelist_options['general'][] = 'default_role';
 
 	$whitelist_options['writing'] = array_merge($whitelist_options['writing'], $mail_options);
diff --git src/wp-includes/ms-functions.php src/wp-includes/ms-functions.php
index f41d2b6..cf96918 100644
--- src/wp-includes/ms-functions.php
+++ src/wp-includes/ms-functions.php
@@ -331,60 +331,6 @@ function get_blog_id_from_url( $domain, $path = '/' ) {
 // Admin functions
 
 /**
- * Checks an email address against a list of banned domains.
- *
- * This function checks against the Banned Email Domains list
- * at wp-admin/network/settings.php. The check is only run on
- * self-registrations; user creation at wp-admin/network/users.php
- * bypasses this check.
- *
- * @since MU
- *
- * @param string $user_email The email provided by the user at registration.
- * @return bool Returns true when the email address is banned.
- */
-function is_email_address_unsafe( $user_email ) {
-	$banned_names = get_site_option( 'banned_email_domains' );
-	if ( $banned_names && ! is_array( $banned_names ) )
-		$banned_names = explode( "\n", $banned_names );
-
-	$is_email_address_unsafe = false;
-
-	if ( $banned_names && is_array( $banned_names ) ) {
-		$banned_names = array_map( 'strtolower', $banned_names );
-		$normalized_email = strtolower( $user_email );
-
-		list( $email_local_part, $email_domain ) = explode( '@', $normalized_email );
-
-		foreach ( $banned_names as $banned_domain ) {
-			if ( ! $banned_domain )
-				continue;
-
-			if ( $email_domain == $banned_domain ) {
-				$is_email_address_unsafe = true;
-				break;
-			}
-
-			$dotted_domain = ".$banned_domain";
-			if ( $dotted_domain === substr( $normalized_email, -strlen( $dotted_domain ) ) ) {
-				$is_email_address_unsafe = true;
-				break;
-			}
-		}
-	}
-
-	/**
-	 * Filter whether an email address is unsafe.
-	 *
-	 * @since 3.5.0
-	 *
-	 * @param bool   $is_email_address_unsafe Whether the email address is "unsafe". Default false.
-	 * @param string $user_email              User email address.
-	 */
-	return apply_filters( 'is_email_address_unsafe', $is_email_address_unsafe, $user_email );
-}
-
-/**
  * Sanitize and validate data required for a user sign-up.
  *
  * Verifies the validity and uniqueness of user names and user email addresses,
@@ -417,8 +363,6 @@ function wpmu_validate_user_signup($user_name, $user_email) {
 		$user_name = $orig_username;
 	}
 
-	$user_email = sanitize_email( $user_email );
-
 	if ( empty( $user_name ) )
 	   	$errors->add('user_name', __( 'Please enter a username.' ) );
 
@@ -438,9 +382,6 @@ function wpmu_validate_user_signup($user_name, $user_email) {
 		$errors->add( 'user_name',  __( 'Sorry, that username is not allowed.' ) );
 	}
 
-	if ( is_email_address_unsafe( $user_email ) )
-		$errors->add('user_email',  __('You cannot use that email address to signup. We are having problems with them blocking some of our email. Please use another email provider.'));
-
 	if ( strlen( $user_name ) < 4 )
 		$errors->add('user_name',  __( 'Username must be at least 4 characters.' ) );
 
@@ -452,14 +393,11 @@ function wpmu_validate_user_signup($user_name, $user_email) {
 	if ( preg_match( '/^[0-9]*$/', $user_name ) )
 		$errors->add('user_name', __('Sorry, usernames must have letters too!'));
 
-	if ( !is_email( $user_email ) )
-		$errors->add('user_email', __( 'Please enter a valid email address.' ) );
-
-	$limited_email_domains = get_site_option( 'limited_email_domains' );
-	if ( is_array( $limited_email_domains ) && ! empty( $limited_email_domains ) ) {
-		$emaildomain = substr( $user_email, 1 + strpos( $user_email, '@' ) );
-		if ( ! in_array( $emaildomain, $limited_email_domains ) ) {
-			$errors->add('user_email', __('Sorry, that email address is not allowed!'));
+	// Check the email address
+	$is_email_valid = validate_user_email( $user_email );
+	if ( true !== $is_email_valid ) {
+		foreach ( $is_email_valid as $email_error ) {
+			$errors->add( 'user_email', $email_error );
 		}
 	}
 
@@ -467,10 +405,6 @@ function wpmu_validate_user_signup($user_name, $user_email) {
 	if ( username_exists($user_name) )
 		$errors->add( 'user_name', __( 'Sorry, that username already exists!' ) );
 
-	// Check if the email address has been used already.
-	if ( email_exists($user_email) )
-		$errors->add( 'user_email', __( 'Sorry, that email address is already used!' ) );
-
 	// Has someone already signed up for this username?
 	$signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE user_login = %s", $user_name) );
 	if ( $signup != null ) {
diff --git src/wp-includes/user.php src/wp-includes/user.php
index 32b0ec7..095a31e 100644
--- src/wp-includes/user.php
+++ src/wp-includes/user.php
@@ -1194,6 +1194,147 @@ function email_exists( $email ) {
 }
 
 /**
+ * Checks an email address against a list of allowed domains.
+ *
+ * This function checks agains the Limited Email Domains list
+ * at wp-admin/network/settings.php or wp-admin/options-general.php.
+ * The check is only run on self-registrations.
+ * User creation at wp-admin/network/users.php or wp-admin/user-new.php
+ * bypasses this check.
+ *
+ * @since ?.?
+ *
+ * @param string $user_email The email provided by the user at registration
+ * @return bool True when the email address is allowed, False otherwise.
+ */
+function is_email_address_allowed( $user_email ) {
+	$is_allowed = true;
+	$limited_email_domains = get_site_option( 'limited_email_domains' );
+
+	if ( is_array( $limited_email_domains ) && empty( $limited_email_domains ) === false ) {
+		$emaildomain = substr( $user_email, 1 + strpos( $user_email, '@' ) );
+
+		if ( ! in_array( $emaildomain, $limited_email_domains ) ) {
+			$is_allowed = false;
+		}
+	}
+
+	/**
+	 * Filter whether an email address is allowed.
+	 *
+	 * @since ?.?
+	 *
+	 * @param bool   $is_allowed Whether the email address is allowed. Default True.
+	 * @param string $user_email User email address.
+	 */
+	return apply_filters( 'is_email_address_allowed', $is_allowed, $user_email );
+}
+
+/**
+ * Checks an email address against a list of banned domains.
+ *
+ * This function checks against the Banned Email Domains list
+ * at wp-admin/network/settings.php or wp-admin/options-general.php.
+ * The check is only run on self-registrations inside.
+ * User creation at wp-admin/network/users.php or wp-admin/user-new.php
+ * bypasses this check.
+ *
+ * @since MU
+ *
+ * @param string $user_email The email provided by the user at registration.
+ * @return bool Returns true when the email address is banned.
+ */
+function is_email_address_unsafe( $user_email ) {
+	$banned_names = get_site_option( 'banned_email_domains' );
+	if ( $banned_names && ! is_array( $banned_names ) ) {
+		$banned_names = explode( "\n", $banned_names );
+	}
+
+	$is_email_address_unsafe = false;
+
+	if ( $banned_names && is_array( $banned_names ) ) {
+		$banned_names = array_map( 'strtolower', $banned_names );
+		$normalized_email = strtolower( $user_email );
+
+		list( $email_local_part, $email_domain ) = explode( '@', $normalized_email );
+
+		foreach ( $banned_names as $banned_domain ) {
+			if ( ! $banned_domain ) {
+				continue;
+			}
+
+			if ( $email_domain == $banned_domain ) {
+				$is_email_address_unsafe = true;
+				break;
+			}
+
+			$dotted_domain = ".$banned_domain";
+			if ( $dotted_domain === substr( $normalized_email, -strlen( $dotted_domain ) ) ) {
+				$is_email_address_unsafe = true;
+				break;
+			}
+		}
+	}
+
+	/**
+	 * Filter whether an email address is unsafe.
+	 *
+	 * @since 3.5.0
+	 *
+	 * @param bool   $is_email_address_unsafe Whether the email address is "unsafe". Default false.
+	 * @param string $user_email              User email address.
+	 */
+	return apply_filters( 'is_email_address_unsafe', $is_email_address_unsafe, $user_email );
+}
+
+/**
+ * Check to see whether an email address is usable for new user registration
+ *
+ * This is a convenience function that wraps several disparate email validators
+ * throughout WordPress:
+ *  - check that an email address is well-formed
+ *  - check that the email domain has not been banned by the admin
+ *  - check that the email domain is on the whitelist, if one exists
+ *  - check that the email address isn't already in use
+ *
+ * @since ?.?
+ *
+ * @param string $user_email The email address to check
+ * @return bool|array True if the email passes all checks; otherwise an array
+ *   of error message strings
+ */
+function validate_user_email( $user_email ) {
+	$errors         = array();
+	$is_email_valid = true;
+
+	$user_email = sanitize_email( $user_email );
+
+	if ( ! is_email( $user_email ) ) {
+		$errors['invalid'] = __( 'Please enter a valid email address.' );
+
+	// Only perform the other checks on a valid email adress
+	} else {
+		if ( is_email_address_unsafe( $user_email ) ) {
+			$errors['domain_banned'] = __( 'You cannot use that email address to signup. We are having problems with them blocking some of our email. Please use another email provider.' );
+		}
+
+		if ( ! is_email_address_allowed( $user_email ) ) {
+			$errors['domain_not_allowed'] = __( 'Sorry, that email address is not allowed!' );
+		}
+
+		if ( email_exists( $user_email ) ) {
+			$errors['in_use'] = __( 'Sorry, that email address is already used!' );
+		}
+	}
+
+	if ( ! empty( $errors ) ) {
+		$is_email_valid = $errors;
+	}
+
+	return apply_filters( 'validate_user_email', $is_email_valid, $user_email );
+}
+
+/**
  * Checks whether a username is valid.
  *
  * @since 2.0.1
@@ -2129,11 +2270,13 @@ function register_new_user( $user_login, $user_email ) {
 	// Check the email address
 	if ( $user_email == '' ) {
 		$errors->add( 'empty_email', __( '<strong>ERROR</strong>: Please type your email address.' ) );
-	} elseif ( ! is_email( $user_email ) ) {
-		$errors->add( 'invalid_email', __( '<strong>ERROR</strong>: The email address isn&#8217;t correct.' ) );
-		$user_email = '';
-	} elseif ( email_exists( $user_email ) ) {
-		$errors->add( 'email_exists', __( '<strong>ERROR</strong>: This email is already registered, please choose another one.' ) );
+	}
+
+	$is_email_valid = validate_user_email( $user_email );
+	if ( true !== $is_email_valid ) {
+		foreach ( $is_email_valid as $email_error ) {
+			$errors->add( 'user_email', sprintf( __( '<strong>ERROR</strong>: %s' ), $email_error ) );
+		}
 	}
 
 	/**
