diff --git a/src/tools/msvc/MSBuildProject.pm b/src/tools/msvc/MSBuildProject.pm
index 149213378c..c5504730c3 100644
--- a/src/tools/msvc/MSBuildProject.pm
+++ b/src/tools/msvc/MSBuildProject.pm
@@ -467,4 +467,27 @@ sub new
 	return $self;
 }
 
+#
+# Package that encapsulates a Visual C++ 2019 project file
+#
+
+use strict;
+use warnings;
+use base qw(MSBuildProject);
+
+no warnings qw(redefine);    ## no critic
+
+sub new
+{
+	my $classname = shift;
+	my $self      = $classname->SUPER::_new(@_);
+	bless($self, $classname);
+
+	$self->{vcver}           = '16.00';
+	$self->{PlatformToolset} = 'v142';
+	$self->{ToolsVersion}    = '16.0';
+
+	return $self;
+}
+
 1;
diff --git a/src/tools/msvc/README b/src/tools/msvc/README
index 4ab81d3402..c7b6575e42 100644
--- a/src/tools/msvc/README
+++ b/src/tools/msvc/README
@@ -4,7 +4,7 @@ MSVC build
 ==========
 
 This directory contains the tools required to build PostgreSQL using
-Microsoft Visual Studio 2013 - 2017. This builds the whole backend, not just
+Microsoft Visual Studio 2013 - 2019. This builds the whole backend, not just
 the libpq frontend library. For more information, see the documentation
 chapter "Installation on Windows" and the description below.
 
@@ -89,10 +89,10 @@ These configuration arguments are passed over to Mkvcbuild::mkvcbuild
 (Mkvcbuild.pm) which creates the Visual Studio project and solution files.
 It does this by using VSObjectFactory::CreateSolution to create an object
 implementing the Solution interface (this could be either a VS2013Solution,
-or a VS2015Solution or a VS2017Solution, all in Solution.pm, depending on
-the user's build environment) and adding objects implementing the corresponding
-Project interface (VC2013Project or VC2015Project or VC2017Project from
-MSBuildProject.pm) to it.
+or a VS2015Solution or a VS2017Solution or a VS2019Solution, all in
+Solution.pm, depending on the user's build environment) and adding objects
+implementing the corresponding Project interface (VC2013Project or 
+VC2015Project or VC2017Project or VC2019Project from MSBuildProject.pm) to it.
 When Solution::Save is called, the implementations of Solution and Project
 save their content in the appropriate format.
 The final step of starting the appropriate build program (msbuild) is
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 2ea224d770..e4afac4524 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -871,6 +871,34 @@ sub new
 	return $self;
 }
 
+package VS2019Solution;
+
+#
+# Package that encapsulates a Visual Studio 2019 solution file
+#
+
+use Carp;
+use strict;
+use warnings;
+use base qw(Solution);
+
+no warnings qw(redefine);    ## no critic
+
+sub new
+{
+	my $classname = shift;
+	my $self      = $classname->SUPER::_new(@_);
+	bless($self, $classname);
+
+	$self->{solutionFileVersion}        = '12.00';
+	$self->{vcver}                      = '16.00';
+	$self->{visualStudioName}           = 'Visual Studio 2019';
+	$self->{VisualStudioVersion}        = '16.0.28803.202';
+	$self->{MinimumVisualStudioVersion} = '10.0.40219.1';
+
+	return $self;
+}
+
 sub GetAdditionalHeaders
 {
 	my ($self, $f) = @_;
diff --git a/src/tools/msvc/VSObjectFactory.pm b/src/tools/msvc/VSObjectFactory.pm
index 1a94cd866e..a5bc7b29be 100644
--- a/src/tools/msvc/VSObjectFactory.pm
+++ b/src/tools/msvc/VSObjectFactory.pm
@@ -39,12 +39,17 @@ sub CreateSolution
 		return new VS2015Solution(@_);
 	}
 
-	# visual 2017 hasn't changed the nmake version to 15, so adjust the check to support it.
-	elsif (($visualStudioVersion ge '14.10')
-		or ($visualStudioVersion eq '15.00'))
+	elsif (($visualStudioVersion ge '14.10'))
 	{
 		return new VS2017Solution(@_);
 	}
+
+	# visual 2019 hasn't changed the nmake version to 15, so adjust the check to support it.
+	elsif (($visualStudioVersion ge '14.20')
+		or ($visualStudioVersion eq '15.00'))
+	{
+		return new VS2019Solution(@_);
+	}
 	else
 	{
 		croak $visualStudioVersion;
@@ -70,12 +75,17 @@ sub CreateProject
 		return new VC2015Project(@_);
 	}
 
-	# visual 2017 hasn't changed the nmake version to 15, so adjust the check to support it.
-	elsif (($visualStudioVersion ge '14.10')
-		or ($visualStudioVersion eq '15.00'))
+	elsif (($visualStudioVersion ge '14.10'))
 	{
 		return new VC2017Project(@_);
 	}
+
+	# visual 2019 hasn't changed the nmake version to 15, so adjust the check to support it.
+	elsif (($visualStudioVersion ge '14.20')
+		or ($visualStudioVersion eq '15.00'))
+	{
+		return new VC2019Project(@_);
+	}
 	else
 	{
 		croak $visualStudioVersion;
@@ -106,7 +116,7 @@ sub _GetVisualStudioVersion
 {
 	my ($major, $minor) = @_;
 
-	# visual 2017 hasn't changed the nmake version to 15, so still using the older version for comparison.
+	# visual 2019 hasn't changed the nmake version to 15, so still using the older version for comparison.
 	if ($major > 14)
 	{
 		carp
