diff --git src/wp-admin/includes/plugin.php src/wp-admin/includes/plugin.php
index c898fc5169..985dba7211 100644
--- src/wp-admin/includes/plugin.php
+++ src/wp-admin/includes/plugin.php
@@ -31,6 +31,8 @@
  *     Network: Optional. Specify "Network: true" to require that a plugin is activated
  *          across all sites in an installation. This will prevent a plugin from being
  *          activated on a single site when Multisite is enabled.
+ *     Requires WP: Optional. Specify the minimum required WordPress version.
+ *     Requires PHP: Optional. Specify the minimum required PHP version.
  *      * / # Remove the space to close comment
  *
  * Some users have issues with opening large files and manipulating the contents
@@ -63,6 +65,9 @@
  *     @type string $TextDomain  Plugin textdomain.
  *     @type string $DomainPath  Plugins relative directory path to .mo files.
  *     @type bool   $Network     Whether the plugin can only be activated network-wide.
+ *     @type string $RequiresWP  Minimum required version of WordPress.
+ *     @type string $RequiresPHP Minimum required version of PHP.
+
  * }
  */
 function get_plugin_data( $plugin_file, $markup = true, $translate = true ) {
@@ -77,6 +82,8 @@ function get_plugin_data( $plugin_file, $markup = true, $translate = true ) {
 		'TextDomain'  => 'Text Domain',
 		'DomainPath'  => 'Domain Path',
 		'Network'     => 'Network',
+		'RequiresWP'  => 'Requires WP',
+		'RequiresPHP' => 'Requires PHP',
 		// Site Wide Only is deprecated in favor of Network.
 		'_sitewide'   => 'Site Wide Only',
 	);
@@ -189,6 +196,52 @@ function _get_plugin_data_markup_translate( $plugin_file, $plugin_data, $markup
 	return $plugin_data;
 }
 
+/**
+ * Get the and return plugin data used for validation.
+ *
+ * Initially use the Plugin API as there's no current method to parse the local plugin readme.txt file.
+ * Alternately see if a plugin header `Requires WP` or `Requires PHP` exists and use that.
+ *
+ * @since 5.1.0
+ * @see validate_plugin_requirements()
+ *
+ * @param string $plugin_file Path to the plugin file relative to the plugins directory.
+ *
+ * @return object $plugin_data Object of plugin data for validation.
+ */
+function get_plugin_validation_data( $plugin_file ) {
+	$plugin_data = new stdClass();
+	$slug        = dirname( $plugin_file );
+	$url         = 'https://api.wordpress.org/plugins/info/1.2/';
+	$url         = add_query_arg(
+		array(
+			'action'                        => 'plugin_information',
+			rawurlencode( 'request[slug]' ) => $slug,
+		),
+		$url
+	);
+	$response    = wp_remote_get( $url );
+	if ( ! is_wp_error( $response ) ) {
+		$plugin_data = json_decode( wp_remote_retrieve_body( $response ) );
+	}
+
+	$invalid_check = isset( $plugin_data->error ) || is_wp_error( $response ) || $slug !== $plugin_data->slug;
+
+	/*
+	 * Plugin is likley not in the WP Plugin Directory but if they have designated
+	 * `Requires WP` and/or `Requires PHP` headers we can use those.
+	 */
+	if ( $invalid_check ) {
+		$plugin_data               = new stdClass();
+		$plugin_data->file         = $plugin_file;
+		$plugin_headers            = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin_file );
+		$plugin_data->requires     = $plugin_headers['RequiresWP'];
+		$plugin_data->requires_php = $plugin_headers['RequiresPHP'];
+	}
+
+	return $plugin_data;
+}
+
 /**
  * Get a list of a plugin's files.
  *
@@ -589,6 +642,10 @@ function activate_plugin( $plugin, $redirect = '', $network_wide = false, $silen
 		return $valid;
 	}
 
+	if ( validate_plugin_requirements( $plugin ) ) {
+		return new WP_Error( 'plugin_activation_error', __( 'Plugin does not meet minimum WordPress and/or PHP requirements.' ) );
+	}
+
 	if ( ( $network_wide && ! isset( $current[ $plugin ] ) ) || ( ! $network_wide && ! in_array( $plugin, $current ) ) ) {
 		if ( ! empty( $redirect ) ) {
 			wp_redirect( add_query_arg( '_error_nonce', wp_create_nonce( 'plugin-activation-error_' . $plugin ), $redirect ) ); // we'll override this later if the plugin can be included without fatal error
@@ -1023,6 +1080,26 @@ function validate_plugin( $plugin ) {
 	return 0;
 }
 
+/**
+ * Validate the plugin requirements for WP version and PHP version.
+ *
+ * @uses get_plugin_validation_data()
+ *
+ * @since 5.1.0
+ * @see activate_plugin()
+ *
+ * @param string $plugin Path to the plugin file relative to the plugins directory.
+ *
+ * @return bool Default to true and if requirements met, false if not.
+ */
+function validate_plugin_requirements( $plugin ) {
+	$plugin_data  = get_plugin_validation_data( $plugin );
+	$wp_requires  = isset( $plugin_data->requires ) ? $plugin_data->requires : null;
+	$php_requires = isset( $plugin_data->requires_php ) ? $plugin_data->requires_php : null;
+
+	return ! ( is_compatible_wp( $wp_requires ) && is_compatible_php( $php_requires ) );
+}
+
 /**
  * Whether the plugin can be uninstalled.
  *
diff --git src/wp-includes/functions.php src/wp-includes/functions.php
index 471fcbb5d6..bfc3142b04 100644
--- src/wp-includes/functions.php
+++ src/wp-includes/functions.php
@@ -6553,3 +6553,30 @@ function wp_privacy_delete_old_export_files() {
 		}
 	}
 }
+
+/**
+ * Check compatibility with current WordPress version.
+ *
+ * @since 5.1.0
+ *
+ * @param string $requires Minimum WordPress version from API.
+ *
+ * @return bool Default true if requirement met or empty, false if not met.
+ */
+function is_compatible_wp( $requires ) {
+	$wp_version = get_bloginfo( 'version' );
+	return ( empty( $requires ) || version_compare( substr( $wp_version, 0, strlen( $requires ) ), $requires, '>=' ) );
+}
+
+/**
+ * Check compatibility with current PHP version.
+ *
+ * @since 5.1.0
+ *
+ * @param string $requires Minimum PHP version from API.
+ *
+ * @return bool Default true if requirement met or empty, false if not met.
+ */
+function is_compatible_php( $requires ) {
+	return ( empty( $requires ) || version_compare( substr( phpversion(), 0, strlen( $requires ) ), $requires, '>=' ) );
+}
