diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx
index 29af9c56d2e0..912820292ee3 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx
+++ b/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx
@@ -232,4 +232,7 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually
   <data name="PrereleaseAndVersionAreNotSupportedAtTheSameTime" xml:space="preserve">
     <value>The --prerelease and --version options are not supported in the same command</value>
   </data>
+  <data name="AllowPackageDowngradeOptionDescription" xml:space="preserve">
+    <value>Allow package downgrade when installing a .NET tool package.</value>
+  </data>
 </root>
\ No newline at end of file
diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs
index 16d68cccd0f9..e39dfb35595c 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs
+++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs
@@ -38,6 +38,8 @@ internal static class ToolInstallCommandParser
             ArgumentHelpName = LocalizableStrings.FrameworkOptionName
         };
 
+        public static readonly Option<bool> AllowPackageDowngradeOption = new Option<bool>("--allow-downgrade", LocalizableStrings.AllowPackageDowngradeOptionDescription);
+
         public static readonly Option<bool> PrereleaseOption = ToolSearchCommandParser.PrereleaseOption;
 
         public static readonly Option<VerbosityOptions> VerbosityOption = CommonOptions.VerbosityOption;
@@ -80,6 +82,7 @@ private static Command ConstructCommand()
             command.AddOption(ToolCommandRestorePassThroughOptions.InteractiveRestoreOption);
             command.AddOption(VerbosityOption);
             command.AddOption(ArchitectureOption);
+            command.AddOption(AllowPackageDowngradeOption);
 
             command.SetHandler((parseResult) => new ToolInstallCommand(parseResult).Execute());
 
diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs
index d7ce6283cda9..4d10768a5ca8 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs
+++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs
@@ -11,6 +11,7 @@
 using Microsoft.DotNet.ToolPackage;
 using Microsoft.DotNet.Tools.Tool.Common;
 using Microsoft.Extensions.EnvironmentAbstractions;
+using NuGet.Packaging;
 
 namespace Microsoft.DotNet.Tools.Tool.Install
 {
@@ -21,6 +22,8 @@ internal class ToolInstallLocalCommand : CommandBase
         private readonly ILocalToolsResolverCache _localToolsResolverCache;
         private readonly ToolInstallLocalInstaller _toolLocalPackageInstaller;
         private readonly IReporter _reporter;
+        private readonly PackageId _packageId;
+        private readonly bool _allowPackageDowngrade;
 
         private readonly string _explicitManifestFile;
 
@@ -42,16 +45,87 @@ public ToolInstallLocalCommand(
             _toolManifestEditor = toolManifestEditor ?? new ToolManifestEditor();
             _localToolsResolverCache = localToolsResolverCache ?? new LocalToolsResolverCache();
             _toolLocalPackageInstaller = new ToolInstallLocalInstaller(parseResult, toolPackageInstaller);
+            _allowPackageDowngrade = parseResult.GetValue(ToolInstallCommandParser.AllowPackageDowngradeOption);
+            _packageId = new PackageId(parseResult.GetValue(ToolUpdateCommandParser.PackageIdArgument));
         }
 
         public override int Execute()
         {
-            FilePath manifestFile = GetManifestFilePath();
+            (FilePath? manifestFileOptional, string warningMessage) =
+                _toolManifestFinder.ExplicitManifestOrFindManifestContainPackageId(_explicitManifestFile, _packageId);
 
-            return Install(manifestFile);
+            if (warningMessage != null)
+            {
+                _reporter.WriteLine(warningMessage.Yellow());
+            }
+
+            var manifestFile = manifestFileOptional ?? GetManifestFilePath();
+            var existingPackageWithPackageId = _toolManifestFinder.Find(manifestFile).Where(p => p.PackageId.Equals(_packageId));
+
+            if (!existingPackageWithPackageId.Any())
+            {
+                return InstallNewTool(manifestFile);
+            }
+
+            var existingPackage = existingPackageWithPackageId.Single();
+            var toolDownloadedPackage = _toolLocalPackageInstaller.Install(manifestFile);
+
+            InstallToolUpdate(existingPackage, toolDownloadedPackage, manifestFile);
+
+            _localToolsResolverCache.SaveToolPackage(
+               toolDownloadedPackage,
+               _toolLocalPackageInstaller.TargetFrameworkToInstall);
+
+            return 0;
+        }
+
+        public int InstallToolUpdate(ToolManifestPackage existingPackage, IToolPackage toolDownloadedPackage, FilePath manifestFile)
+        {
+            if (existingPackage.Version > toolDownloadedPackage.Version && !_allowPackageDowngrade)
+            {
+                throw new GracefulException(new[]
+                    {
+                        string.Format(
+                            Update.LocalizableStrings.UpdateLocalToolToLowerVersion,
+                            toolDownloadedPackage.Version.ToNormalizedString(),
+                            existingPackage.Version.ToNormalizedString(),
+                            manifestFile.Value)
+                    },
+                    isUserError: false);
+            }
+            else if (existingPackage.Version == toolDownloadedPackage.Version)
+            {
+                _reporter.WriteLine(
+                    string.Format(
+                        Update.LocalizableStrings.UpdateLocaToolSucceededVersionNoChange,
+                        toolDownloadedPackage.Id,
+                        existingPackage.Version.ToNormalizedString(),
+                        manifestFile.Value));
+            }
+            else
+            {
+                _toolManifestEditor.Edit(
+                    manifestFile,
+                    _packageId,
+                    toolDownloadedPackage.Version,
+                    toolDownloadedPackage.Commands.Select(c => c.Name).ToArray());
+                _reporter.WriteLine(
+                    string.Format(
+                        Update.LocalizableStrings.UpdateLocalToolSucceeded,
+                        toolDownloadedPackage.Id,
+                        existingPackage.Version.ToNormalizedString(),
+                        toolDownloadedPackage.Version.ToNormalizedString(),
+                        manifestFile.Value).Green());
+            }
+
+            _localToolsResolverCache.SaveToolPackage(
+                toolDownloadedPackage,
+                _toolLocalPackageInstaller.TargetFrameworkToInstall);
+
+            return 0;
         }
 
-        public int Install(FilePath manifestFile)
+        public int InstallNewTool(FilePath manifestFile)
         {
             IToolPackage toolDownloadedPackage =
                 _toolLocalPackageInstaller.Install(manifestFile);
diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf
index db5de960bf3b..6459c3b31905 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf
@@ -2,6 +2,11 @@
 <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
   <file datatype="xml" source-language="en" target-language="cs" original="../LocalizableStrings.resx">
     <body>
+      <trans-unit id="AllowPackageDowngradeOptionDescription">
+        <source>Allow package downgrade when installing a .NET tool package.</source>
+        <target state="new">Allow package downgrade when installing a .NET tool package.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="InstallToolCommandInvalidGlobalAndLocalAndToolPath">
         <source>The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}.</source>
         <target state="translated">Možnost local (--local), možnost global (--global), možnost tool path (--tool-path), v jednu chvíli je možné mít jen jednu. Zadejte jen jednu z možností: {0}</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf
index 8cd539b174a1..d40e23894ff9 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf
@@ -2,6 +2,11 @@
 <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
   <file datatype="xml" source-language="en" target-language="de" original="../LocalizableStrings.resx">
     <body>
+      <trans-unit id="AllowPackageDowngradeOptionDescription">
+        <source>Allow package downgrade when installing a .NET tool package.</source>
+        <target state="new">Allow package downgrade when installing a .NET tool package.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="InstallToolCommandInvalidGlobalAndLocalAndToolPath">
         <source>The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}.</source>
         <target state="translated">Die lokale Option (--local), die globale Option (--global) und die Toolpfadoption (--tool-path) können nicht zusammen angegeben werden. Geben Sie nur eine der Optionen an: {0}.</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf
index 3cc779b5a9ec..4964c331ce62 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf
@@ -2,6 +2,11 @@
 <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
   <file datatype="xml" source-language="en" target-language="es" original="../LocalizableStrings.resx">
     <body>
+      <trans-unit id="AllowPackageDowngradeOptionDescription">
+        <source>Allow package downgrade when installing a .NET tool package.</source>
+        <target state="new">Allow package downgrade when installing a .NET tool package.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="InstallToolCommandInvalidGlobalAndLocalAndToolPath">
         <source>The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}.</source>
         <target state="translated">La opción local (--local), la opción global (--global) y la opción de ruta de acceso de herramienta (--tool-path), solo pueden estar una cada vez. Especifique solo una de las opciones: {0}.</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf
index 44de3243301a..07a41d0ec970 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf
@@ -2,6 +2,11 @@
 <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
   <file datatype="xml" source-language="en" target-language="fr" original="../LocalizableStrings.resx">
     <body>
+      <trans-unit id="AllowPackageDowngradeOptionDescription">
+        <source>Allow package downgrade when installing a .NET tool package.</source>
+        <target state="new">Allow package downgrade when installing a .NET tool package.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="InstallToolCommandInvalidGlobalAndLocalAndToolPath">
         <source>The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}.</source>
         <target state="translated">L'option locale (--local), l'option globale (--global) et l'option de chemin d'outil (--tool-path) ne peuvent pas être utilisées simultanément. Spécifiez une seule des options : {0}.</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf
index d34477f2f16f..21557fa7a766 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf
@@ -2,6 +2,11 @@
 <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
   <file datatype="xml" source-language="en" target-language="it" original="../LocalizableStrings.resx">
     <body>
+      <trans-unit id="AllowPackageDowngradeOptionDescription">
+        <source>Allow package downgrade when installing a .NET tool package.</source>
+        <target state="new">Allow package downgrade when installing a .NET tool package.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="InstallToolCommandInvalidGlobalAndLocalAndToolPath">
         <source>The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}.</source>
         <target state="translated">Le opzioni locale (--local), globale (--global) e del percorso dello strumento (--tool-path) non possono essere specificate contemporaneamente. Specificare una sola di queste opzioni: {0}.</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf
index 8f4ad86b0c9c..1d00e40a237d 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf
@@ -2,6 +2,11 @@
 <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
   <file datatype="xml" source-language="en" target-language="ja" original="../LocalizableStrings.resx">
     <body>
+      <trans-unit id="AllowPackageDowngradeOptionDescription">
+        <source>Allow package downgrade when installing a .NET tool package.</source>
+        <target state="new">Allow package downgrade when installing a .NET tool package.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="InstallToolCommandInvalidGlobalAndLocalAndToolPath">
         <source>The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}.</source>
         <target state="translated">ローカル オプション (--local)、グローバル オプション (--global)、ツール パス オプション (--tool-path) は、一度に 1 つだけ指定できます。オプションを 1 つだけ指定します: {0}。</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf
index 3c9ad5c9da16..895a7bfbd3ce 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf
@@ -2,6 +2,11 @@
 <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
   <file datatype="xml" source-language="en" target-language="ko" original="../LocalizableStrings.resx">
     <body>
+      <trans-unit id="AllowPackageDowngradeOptionDescription">
+        <source>Allow package downgrade when installing a .NET tool package.</source>
+        <target state="new">Allow package downgrade when installing a .NET tool package.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="InstallToolCommandInvalidGlobalAndLocalAndToolPath">
         <source>The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}.</source>
         <target state="translated">로컬 옵션(--local), 전역 옵션(--global), 도구 경로 옵션(--tool-path)은 한 번에 하나씩만 사용할 수 있습니다. {0} 옵션 중에서 하나만 지정하세요.</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf
index 1311466b5f84..2484d5b56de1 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf
@@ -2,6 +2,11 @@
 <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
   <file datatype="xml" source-language="en" target-language="pl" original="../LocalizableStrings.resx">
     <body>
+      <trans-unit id="AllowPackageDowngradeOptionDescription">
+        <source>Allow package downgrade when installing a .NET tool package.</source>
+        <target state="new">Allow package downgrade when installing a .NET tool package.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="InstallToolCommandInvalidGlobalAndLocalAndToolPath">
         <source>The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}.</source>
         <target state="translated">Można określić tylko jedną opcję jednocześnie: opcję lokalną (--local), opcję globalną (--global) lub opcję ścieżki do narzędzia (--tool-path). Podaj tylko jedną z opcji: {0}.</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf
index 9bfcc4746408..9fa77fb02b12 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf
@@ -2,6 +2,11 @@
 <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
   <file datatype="xml" source-language="en" target-language="pt-BR" original="../LocalizableStrings.resx">
     <body>
+      <trans-unit id="AllowPackageDowngradeOptionDescription">
+        <source>Allow package downgrade when installing a .NET tool package.</source>
+        <target state="new">Allow package downgrade when installing a .NET tool package.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="InstallToolCommandInvalidGlobalAndLocalAndToolPath">
         <source>The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}.</source>
         <target state="translated">As opções local (--local), global (--global) e do caminho da ferramenta (--tool-path) só podem ocorrer uma por vez. Especifique apenas uma das opções: {0}.</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf
index 949c3d47bf95..6042bdf68f04 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf
@@ -2,6 +2,11 @@
 <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
   <file datatype="xml" source-language="en" target-language="ru" original="../LocalizableStrings.resx">
     <body>
+      <trans-unit id="AllowPackageDowngradeOptionDescription">
+        <source>Allow package downgrade when installing a .NET tool package.</source>
+        <target state="new">Allow package downgrade when installing a .NET tool package.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="InstallToolCommandInvalidGlobalAndLocalAndToolPath">
         <source>The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}.</source>
         <target state="translated">Локальный параметр (--local), глобальный параметр (--global) и параметр пути к средству (--tool-path) можно использовать только отдельно друг от друга. Укажите только один из этих параметров: {0}.</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf
index 10dbd2b76417..4bc76b55e5a9 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf
@@ -2,6 +2,11 @@
 <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
   <file datatype="xml" source-language="en" target-language="tr" original="../LocalizableStrings.resx">
     <body>
+      <trans-unit id="AllowPackageDowngradeOptionDescription">
+        <source>Allow package downgrade when installing a .NET tool package.</source>
+        <target state="new">Allow package downgrade when installing a .NET tool package.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="InstallToolCommandInvalidGlobalAndLocalAndToolPath">
         <source>The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}.</source>
         <target state="translated">Yerel seçeneği (--local), genel seçeneği (--global), araç yolu seçeneği (--tool-path) arasından yalnızca biri seçilebilir. Seçeneklerden yalnızca birini belirtin: {0}.</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf
index 52f09eda7162..edc736291ca8 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf
@@ -2,6 +2,11 @@
 <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
   <file datatype="xml" source-language="en" target-language="zh-Hans" original="../LocalizableStrings.resx">
     <body>
+      <trans-unit id="AllowPackageDowngradeOptionDescription">
+        <source>Allow package downgrade when installing a .NET tool package.</source>
+        <target state="new">Allow package downgrade when installing a .NET tool package.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="InstallToolCommandInvalidGlobalAndLocalAndToolPath">
         <source>The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}.</source>
         <target state="translated">本地选项(--local)、全局选项(--global)和工具路径选项(--tool-path)一次只能有一个。请仅指定其中一个选项: {0}。</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf
index 6455ca572461..a33f6d522125 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf
@@ -2,6 +2,11 @@
 <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
   <file datatype="xml" source-language="en" target-language="zh-Hant" original="../LocalizableStrings.resx">
     <body>
+      <trans-unit id="AllowPackageDowngradeOptionDescription">
+        <source>Allow package downgrade when installing a .NET tool package.</source>
+        <target state="new">Allow package downgrade when installing a .NET tool package.</target>
+        <note />
+      </trans-unit>
       <trans-unit id="InstallToolCommandInvalidGlobalAndLocalAndToolPath">
         <source>The local option(--local), the global option (--global), the tool path option (--tool-path), can only have one at a time. Specify only one of the options: {0}.</source>
         <target state="translated">一次只能有一個本機選項 (--local)、全域選項 (--global)、工具路徑選項 (--tool-path)。請僅指定其中一個選項: {0}。</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-tool/update/LocalizableStrings.resx
index af3c3cf46ee8..5337b9218764 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/update/LocalizableStrings.resx
+++ b/src/Cli/dotnet/commands/dotnet-tool/update/LocalizableStrings.resx
@@ -218,10 +218,10 @@ and the corresponding package Ids for installed tools using the command
   <data name="UpdateLocalToolSucceeded" xml:space="preserve">
     <value>Tool '{0}' was successfully updated from version '{1}' to version '{2}' (manifest file {3}).</value>
   </data>
-  <data name="UpdateLocaToolToLowerVersion" xml:space="preserve">
+  <data name="UpdateLocalToolToLowerVersion" xml:space="preserve">
     <value>The requested version {0} is lower than existing version {1} (manifest file {2}).</value>
   </data>
   <data name="UpdateLocaToolSucceededVersionNoChange" xml:space="preserve">
     <value>Tool '{0}' is up to date (version '{1}' manifest file {2}) .</value>
   </data>
-</root>
+</root>
\ No newline at end of file
diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateLocalCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateLocalCommand.cs
index eab2f40b32ea..6dd875081a38 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateLocalCommand.cs
+++ b/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateLocalCommand.cs
@@ -74,74 +74,8 @@ public ToolUpdateLocalCommand(
 
         public override int Execute()
         {
-            (FilePath? manifestFileOptional, string warningMessage) = 
-                _toolManifestFinder.ExplicitManifestOrFindManifestContainPackageId(_explicitManifestFile, _packageId);
-
-            var manifestFile = manifestFileOptional ?? _toolManifestFinder.FindFirst();
-
-            var toolDownloadedPackage = _toolLocalPackageInstaller.Install(manifestFile);
-            var existingPackageWithPackageId =
-                _toolManifestFinder
-                    .Find(manifestFile)
-                    .Where(p => p.PackageId.Equals(_packageId));
-
-            if (!existingPackageWithPackageId.Any())
-            {
-                return _toolInstallLocalCommand.Value.Install(manifestFile);
-            }
-
-            var existingPackage = existingPackageWithPackageId.Single();
-            if (existingPackage.Version > toolDownloadedPackage.Version)
-            {
-                throw new GracefulException(new[]
-                    {
-                        string.Format(
-                            LocalizableStrings.UpdateLocaToolToLowerVersion,
-                            toolDownloadedPackage.Version.ToNormalizedString(),
-                            existingPackage.Version.ToNormalizedString(),
-                            manifestFile.Value)
-                    },
-                    isUserError: false);
-            }
-
-            if (existingPackage.Version != toolDownloadedPackage.Version)
-            {
-                _toolManifestEditor.Edit(
-                    manifestFile,
-                    _packageId,
-                    toolDownloadedPackage.Version,
-                    toolDownloadedPackage.Commands.Select(c => c.Name).ToArray());
-            }
-
-            _localToolsResolverCache.SaveToolPackage(
-                toolDownloadedPackage,
-                _toolLocalPackageInstaller.TargetFrameworkToInstall);
-
-            if (warningMessage != null)
-            {
-                _reporter.WriteLine(warningMessage.Yellow());
-            }
-
-            if (existingPackage.Version == toolDownloadedPackage.Version)
-            {
-                _reporter.WriteLine(
-                    string.Format(
-                        LocalizableStrings.UpdateLocaToolSucceededVersionNoChange,
-                        toolDownloadedPackage.Id,
-                        existingPackage.Version.ToNormalizedString(),
-                        manifestFile.Value));
-            }
-            else
-            {
-                _reporter.WriteLine(
-                    string.Format(
-                        LocalizableStrings.UpdateLocalToolSucceeded,
-                        toolDownloadedPackage.Id,
-                        existingPackage.Version.ToNormalizedString(),
-                        toolDownloadedPackage.Version.ToNormalizedString(),
-                        manifestFile.Value).Green());
-            }
-
+            _toolInstallLocalCommand.Value.Execute();
+            
             return 0;
         }
     }
diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.cs.xlf
index 49017f3ead99..65296bb3cbca 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.cs.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.cs.xlf
@@ -42,16 +42,16 @@
         <target state="translated">Nástroj {0} je aktuální (verze {1}, soubor manifestu {2}).</target>
         <note />
       </trans-unit>
-      <trans-unit id="UpdateLocaToolToLowerVersion">
-        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
-        <target state="translated">Požadovaná verze {0} je nižší než stávající verze {1} (soubor manifestu {2}).</target>
-        <note />
-      </trans-unit>
       <trans-unit id="UpdateLocalToolSucceeded">
         <source>Tool '{0}' was successfully updated from version '{1}' to version '{2}' (manifest file {3}).</source>
         <target state="translated">Nástroj {0} byl úspěšně aktualizován z verze {1} na verzi {2} (soubor manifestu {3}).</target>
         <note />
       </trans-unit>
+      <trans-unit id="UpdateLocalToolToLowerVersion">
+        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
+        <target state="new">The requested version {0} is lower than existing version {1} (manifest file {2}).</target>
+        <note />
+      </trans-unit>
       <trans-unit id="UpdateSucceededPreVersionNoChange">
         <source>Tool '{0}' was reinstalled with the latest prerelease version (version '{1}').</source>
         <target state="translated">Nástroj{0}byl znovu nainstalován s nejnovější předběžnou verzí (verze{1}).</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.de.xlf
index 36cf57b95ead..286a1bfbb200 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.de.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.de.xlf
@@ -42,16 +42,16 @@
         <target state="translated">Das Tool "{0}" ist auf dem neuesten Stand (Version {1}, Manifestdatei "{2}").</target>
         <note />
       </trans-unit>
-      <trans-unit id="UpdateLocaToolToLowerVersion">
-        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
-        <target state="translated">Die angeforderte Version {0} ist niedriger als die vorhandene Version {1} (Manifestdatei "{2}").</target>
-        <note />
-      </trans-unit>
       <trans-unit id="UpdateLocalToolSucceeded">
         <source>Tool '{0}' was successfully updated from version '{1}' to version '{2}' (manifest file {3}).</source>
         <target state="translated">Das Tool "{0}" wurde erfolgreich von Version {1} auf Version {2} aktualisiert (Manifestdatei "{3}").</target>
         <note />
       </trans-unit>
+      <trans-unit id="UpdateLocalToolToLowerVersion">
+        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
+        <target state="new">The requested version {0} is lower than existing version {1} (manifest file {2}).</target>
+        <note />
+      </trans-unit>
       <trans-unit id="UpdateSucceededPreVersionNoChange">
         <source>Tool '{0}' was reinstalled with the latest prerelease version (version '{1}').</source>
         <target state="translated">Das Tool „{0}“ wurde in der neuesten Vorabversion neu installiert (Version „{1}“).</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.es.xlf
index e57a011b7607..d127885daa80 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.es.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.es.xlf
@@ -42,16 +42,16 @@
         <target state="translated">La herramienta "{0}" está actualizada (versión "{1}", archivo de manifiesto {2}) .</target>
         <note />
       </trans-unit>
-      <trans-unit id="UpdateLocaToolToLowerVersion">
-        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
-        <target state="translated">La versión solicitada {0} es anterior a la versión existente {1} (archivo de manifiesto {2}).</target>
-        <note />
-      </trans-unit>
       <trans-unit id="UpdateLocalToolSucceeded">
         <source>Tool '{0}' was successfully updated from version '{1}' to version '{2}' (manifest file {3}).</source>
         <target state="translated">La herramienta "{0}" se actualizó correctamente de la versión "{1}" a la versión "{2}" (archivo de manifiesto {3}).</target>
         <note />
       </trans-unit>
+      <trans-unit id="UpdateLocalToolToLowerVersion">
+        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
+        <target state="new">The requested version {0} is lower than existing version {1} (manifest file {2}).</target>
+        <note />
+      </trans-unit>
       <trans-unit id="UpdateSucceededPreVersionNoChange">
         <source>Tool '{0}' was reinstalled with the latest prerelease version (version '{1}').</source>
         <target state="translated">La herramienta "{0}" se ha reinstalado con la versión preliminar más reciente (versión "{1}").</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.fr.xlf
index 4bf16511cbb6..0efd80b9ed91 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.fr.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.fr.xlf
@@ -42,16 +42,16 @@
         <target state="translated">L'outil '{0}' est à jour (version '{1}', fichier manifeste {2}).</target>
         <note />
       </trans-unit>
-      <trans-unit id="UpdateLocaToolToLowerVersion">
-        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
-        <target state="translated">La version demandée {0} est inférieure à la version existante {1} (fichier manifeste {2}).</target>
-        <note />
-      </trans-unit>
       <trans-unit id="UpdateLocalToolSucceeded">
         <source>Tool '{0}' was successfully updated from version '{1}' to version '{2}' (manifest file {3}).</source>
         <target state="translated">L'outil '{0}' a été correctement mis à jour de la version '{1}' à la version '{2}' (fichier manifeste {3}).</target>
         <note />
       </trans-unit>
+      <trans-unit id="UpdateLocalToolToLowerVersion">
+        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
+        <target state="new">The requested version {0} is lower than existing version {1} (manifest file {2}).</target>
+        <note />
+      </trans-unit>
       <trans-unit id="UpdateSucceededPreVersionNoChange">
         <source>Tool '{0}' was reinstalled with the latest prerelease version (version '{1}').</source>
         <target state="translated">L'outil '{0}' a été réinstallé avec la dernière version préliminaire (version '{1}').</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.it.xlf
index 1b64464c6117..536836352698 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.it.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.it.xlf
@@ -42,16 +42,16 @@
         <target state="translated">Lo strumento '{0}' è aggiornato (file manifesto {2} versione '{1}').</target>
         <note />
       </trans-unit>
-      <trans-unit id="UpdateLocaToolToLowerVersion">
-        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
-        <target state="translated">La versione richiesta {0} è inferiore a quella esistente {1} (file manifesto {2}).</target>
-        <note />
-      </trans-unit>
       <trans-unit id="UpdateLocalToolSucceeded">
         <source>Tool '{0}' was successfully updated from version '{1}' to version '{2}' (manifest file {3}).</source>
         <target state="translated">Lo strumento '{0}' è stato aggiornato dalla versione '{1}' alla versione '{2}' (file manifesto {3}).</target>
         <note />
       </trans-unit>
+      <trans-unit id="UpdateLocalToolToLowerVersion">
+        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
+        <target state="new">The requested version {0} is lower than existing version {1} (manifest file {2}).</target>
+        <note />
+      </trans-unit>
       <trans-unit id="UpdateSucceededPreVersionNoChange">
         <source>Tool '{0}' was reinstalled with the latest prerelease version (version '{1}').</source>
         <target state="translated">Lo strumento '{0}' è stato reinstallato con l'ultima versione preliminare (versione '{1}').</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.ja.xlf
index 3d7d560ea2a2..d04705c2d983 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.ja.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.ja.xlf
@@ -42,16 +42,16 @@
         <target state="translated">ツール '{0}' は最新の状態です (バージョン '{1}' マニフェスト ファイル {2})。</target>
         <note />
       </trans-unit>
-      <trans-unit id="UpdateLocaToolToLowerVersion">
-        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
-        <target state="translated">要求されたバージョン {0} は、既存のバージョン {1} (マニフェスト ファイル {2}) よりも低くなっています。</target>
-        <note />
-      </trans-unit>
       <trans-unit id="UpdateLocalToolSucceeded">
         <source>Tool '{0}' was successfully updated from version '{1}' to version '{2}' (manifest file {3}).</source>
         <target state="translated">ツール '{0}' がバージョン '{1}' からバージョン '{2}' (マニフェストファイル {3}) に正常に更新されました。</target>
         <note />
       </trans-unit>
+      <trans-unit id="UpdateLocalToolToLowerVersion">
+        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
+        <target state="new">The requested version {0} is lower than existing version {1} (manifest file {2}).</target>
+        <note />
+      </trans-unit>
       <trans-unit id="UpdateSucceededPreVersionNoChange">
         <source>Tool '{0}' was reinstalled with the latest prerelease version (version '{1}').</source>
         <target state="translated">ツール '{0}' は、最新のプレリリース バージョン (バージョン '{1}') で再インストールされました。</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.ko.xlf
index e89364423fa2..f1defd809a8a 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.ko.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.ko.xlf
@@ -42,16 +42,16 @@
         <target state="translated">'{0}' 도구는 최신 버전(버전 '{1}' 매니페스트 파일 {2})입니다.</target>
         <note />
       </trans-unit>
-      <trans-unit id="UpdateLocaToolToLowerVersion">
-        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
-        <target state="translated">요청된 버전 {0}이(가) 기존 버전 {1}(매니페스트 파일 {2})보다 낮습니다.</target>
-        <note />
-      </trans-unit>
       <trans-unit id="UpdateLocalToolSucceeded">
         <source>Tool '{0}' was successfully updated from version '{1}' to version '{2}' (manifest file {3}).</source>
         <target state="translated">'{0}' 도구가 '{1}' 버전에서 '{2}' 버전(매니페스트 파일 {3})으로 업데이트되었습니다.</target>
         <note />
       </trans-unit>
+      <trans-unit id="UpdateLocalToolToLowerVersion">
+        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
+        <target state="new">The requested version {0} is lower than existing version {1} (manifest file {2}).</target>
+        <note />
+      </trans-unit>
       <trans-unit id="UpdateSucceededPreVersionNoChange">
         <source>Tool '{0}' was reinstalled with the latest prerelease version (version '{1}').</source>
         <target state="translated">도구 '{0}'이(가) 최신 시험판 버전(버전 '{1}')으로 다시 설치되었습니다.</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.pl.xlf
index d9ebce6c0772..21a57d09c0b2 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.pl.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.pl.xlf
@@ -42,16 +42,16 @@
         <target state="translated">Narzędzie „{0}” jest aktualne (wersja „{1}”, plik manifestu {2}).</target>
         <note />
       </trans-unit>
-      <trans-unit id="UpdateLocaToolToLowerVersion">
-        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
-        <target state="translated">Żądana wersja {0} jest niższa niż obecna wersja {1} (plik manifestu {2}).</target>
-        <note />
-      </trans-unit>
       <trans-unit id="UpdateLocalToolSucceeded">
         <source>Tool '{0}' was successfully updated from version '{1}' to version '{2}' (manifest file {3}).</source>
         <target state="translated">Narzędzie „{0}” zostało pomyślnie zaktualizowane z wersji „{1}” do wersji „{2}” (plik manifestu {3}).</target>
         <note />
       </trans-unit>
+      <trans-unit id="UpdateLocalToolToLowerVersion">
+        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
+        <target state="new">The requested version {0} is lower than existing version {1} (manifest file {2}).</target>
+        <note />
+      </trans-unit>
       <trans-unit id="UpdateSucceededPreVersionNoChange">
         <source>Tool '{0}' was reinstalled with the latest prerelease version (version '{1}').</source>
         <target state="translated">Narzędzie „{0}” zostało ponownie zainstalowane przy użyciu najnowszej stabilnej wersji (wersja „{1}”).</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.pt-BR.xlf
index 88f0816772ae..6b69485a2294 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.pt-BR.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.pt-BR.xlf
@@ -42,16 +42,16 @@
         <target state="translated">A ferramenta '{0}' está atualizada (versão '{1}' arquivo de manifesto {2}) .</target>
         <note />
       </trans-unit>
-      <trans-unit id="UpdateLocaToolToLowerVersion">
-        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
-        <target state="translated">A versão solicitada {0} é inferior à versão existente {1} (arquivo de manifesto {2}).</target>
-        <note />
-      </trans-unit>
       <trans-unit id="UpdateLocalToolSucceeded">
         <source>Tool '{0}' was successfully updated from version '{1}' to version '{2}' (manifest file {3}).</source>
         <target state="translated">A ferramenta '{0}' foi atualizada com êxito da versão '{1}' para a versão '{2}' (arquivo de manifesto {3}).</target>
         <note />
       </trans-unit>
+      <trans-unit id="UpdateLocalToolToLowerVersion">
+        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
+        <target state="new">The requested version {0} is lower than existing version {1} (manifest file {2}).</target>
+        <note />
+      </trans-unit>
       <trans-unit id="UpdateSucceededPreVersionNoChange">
         <source>Tool '{0}' was reinstalled with the latest prerelease version (version '{1}').</source>
         <target state="translated">A ferramenta '{0}' foi reinstalada com a versão de pré-lançamento mais recente (versão '{1}').</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.ru.xlf
index 46bf064da5cd..74a00df1d768 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.ru.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.ru.xlf
@@ -42,16 +42,16 @@
         <target state="translated">Средство "{0}" обновлено (версия "{1}", файл манифеста {2}).</target>
         <note />
       </trans-unit>
-      <trans-unit id="UpdateLocaToolToLowerVersion">
-        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
-        <target state="translated">Запрошенная версия {0} ниже существующей версии {1} (файл манифеста {2}).</target>
-        <note />
-      </trans-unit>
       <trans-unit id="UpdateLocalToolSucceeded">
         <source>Tool '{0}' was successfully updated from version '{1}' to version '{2}' (manifest file {3}).</source>
         <target state="translated">Средство "{0}" обновлено с версии "{1}" до версии "{2}" (файл манифеста {3}).</target>
         <note />
       </trans-unit>
+      <trans-unit id="UpdateLocalToolToLowerVersion">
+        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
+        <target state="new">The requested version {0} is lower than existing version {1} (manifest file {2}).</target>
+        <note />
+      </trans-unit>
       <trans-unit id="UpdateSucceededPreVersionNoChange">
         <source>Tool '{0}' was reinstalled with the latest prerelease version (version '{1}').</source>
         <target state="translated">Инструмент "{0}" был переустановлен с последней предварительной версией (версией "{1}").</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.tr.xlf
index 9ae1020925b0..d81ada20c78c 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.tr.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.tr.xlf
@@ -42,16 +42,16 @@
         <target state="translated">'{0}' aracı güncel (sürüm '{1}' bildirim dosyası {2}).</target>
         <note />
       </trans-unit>
-      <trans-unit id="UpdateLocaToolToLowerVersion">
-        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
-        <target state="translated">İstenen sürüm ({0}) mevcut sürümünden ({1}) (bildirim dosyası {2}) düşük.</target>
-        <note />
-      </trans-unit>
       <trans-unit id="UpdateLocalToolSucceeded">
         <source>Tool '{0}' was successfully updated from version '{1}' to version '{2}' (manifest file {3}).</source>
         <target state="translated">'{0}' aracı, '{1}' sürümünden '{2}' (bildirim dosyası {3}) sürümüne başarıyla güncelleştirildi.</target>
         <note />
       </trans-unit>
+      <trans-unit id="UpdateLocalToolToLowerVersion">
+        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
+        <target state="new">The requested version {0} is lower than existing version {1} (manifest file {2}).</target>
+        <note />
+      </trans-unit>
       <trans-unit id="UpdateSucceededPreVersionNoChange">
         <source>Tool '{0}' was reinstalled with the latest prerelease version (version '{1}').</source>
         <target state="translated">'{0}' aracı, en yeni ön sürüm (sürüm '{1}') ile yeniden yüklendi.</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.zh-Hans.xlf
index a7264b53a603..06aa58b846fe 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.zh-Hans.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.zh-Hans.xlf
@@ -42,16 +42,16 @@
         <target state="translated">工具“{0}”是最新的(版本“{1}”清单文件 {2})。</target>
         <note />
       </trans-unit>
-      <trans-unit id="UpdateLocaToolToLowerVersion">
-        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
-        <target state="translated">请求的版本 {0} 低于现有版本 {1} (清单文件{2})。</target>
-        <note />
-      </trans-unit>
       <trans-unit id="UpdateLocalToolSucceeded">
         <source>Tool '{0}' was successfully updated from version '{1}' to version '{2}' (manifest file {3}).</source>
         <target state="translated">工具“{0}”已成功从版本“{1}”更新到版本“{2}”(清单文件 {3})。</target>
         <note />
       </trans-unit>
+      <trans-unit id="UpdateLocalToolToLowerVersion">
+        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
+        <target state="new">The requested version {0} is lower than existing version {1} (manifest file {2}).</target>
+        <note />
+      </trans-unit>
       <trans-unit id="UpdateSucceededPreVersionNoChange">
         <source>Tool '{0}' was reinstalled with the latest prerelease version (version '{1}').</source>
         <target state="translated">工具“{0}”已重新安装最新预发行版本(版本“{1}”)。</target>
diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.zh-Hant.xlf
index 24f4b489a06f..3543343886be 100644
--- a/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.zh-Hant.xlf
+++ b/src/Cli/dotnet/commands/dotnet-tool/update/xlf/LocalizableStrings.zh-Hant.xlf
@@ -42,16 +42,16 @@
         <target state="translated">工具 '{0}' 為最新 (版本 '{1}' 資訊清單檔 {2})。</target>
         <note />
       </trans-unit>
-      <trans-unit id="UpdateLocaToolToLowerVersion">
-        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
-        <target state="translated">要求的版本 {0} 低於現有版本 {1} (資訊清單檔 {2})。</target>
-        <note />
-      </trans-unit>
       <trans-unit id="UpdateLocalToolSucceeded">
         <source>Tool '{0}' was successfully updated from version '{1}' to version '{2}' (manifest file {3}).</source>
         <target state="translated">已成功將工具 '{0}' 從 '{1}' 版更新為 '{2}' 版 (資訊清單檔 {3})。</target>
         <note />
       </trans-unit>
+      <trans-unit id="UpdateLocalToolToLowerVersion">
+        <source>The requested version {0} is lower than existing version {1} (manifest file {2}).</source>
+        <target state="new">The requested version {0} is lower than existing version {1} (manifest file {2}).</target>
+        <note />
+      </trans-unit>
       <trans-unit id="UpdateSucceededPreVersionNoChange">
         <source>Tool '{0}' was reinstalled with the latest prerelease version (version '{1}').</source>
         <target state="translated">已使用最新搶鮮版 ('{0}' 版) 來重新安裝工具 '{1}'。</target>
diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolInstallLocalCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolInstallLocalCommandTests.cs
index 281bc27abe77..0905f013c9f2 100644
--- a/src/Tests/dotnet.Tests/CommandTests/ToolInstallLocalCommandTests.cs
+++ b/src/Tests/dotnet.Tests/CommandTests/ToolInstallLocalCommandTests.cs
@@ -22,6 +22,7 @@
 using System.CommandLine;
 using System.CommandLine.Parsing;
 using Parser = Microsoft.DotNet.Cli.Parser;
+using Microsoft.Build.Evaluation;
 
 namespace Microsoft.DotNet.Tests.Commands.Tool
 {
@@ -38,13 +39,16 @@ public class ToolInstallLocalCommandTests
         private readonly string _manifestFilePath;
         private readonly PackageId _packageIdA = new PackageId("local.tool.console.a");
         private readonly NuGetVersion _packageVersionA;
+        private readonly NuGetVersion _packageNewVersionA;
         private readonly ToolCommandName _toolCommandNameA = new ToolCommandName("a");
         private readonly ToolManifestFinder _toolManifestFinder;
         private readonly ToolManifestEditor _toolManifestEditor;
+        private readonly MockFeed _mockFeed;
 
         public ToolInstallLocalCommandTests()
         {
             _packageVersionA = NuGetVersion.Parse("1.0.4");
+            _packageNewVersionA = NuGetVersion.Parse("2.0.0");
 
             _reporter = new BufferedReporter();
             _fileSystem = new FileSystemMockBuilder().UseCurrentSystemTemporaryDirectory().Build();
@@ -53,18 +57,10 @@ public ToolInstallLocalCommandTests()
             ToolPackageStoreMock toolPackageStoreMock =
                 new ToolPackageStoreMock(new DirectoryPath(_pathToPlacePackages), _fileSystem);
             _toolPackageStore = toolPackageStoreMock;
-            _toolPackageInstallerMock = new ToolPackageInstallerMock(
-                _fileSystem,
-                _toolPackageStore,
-                new ProjectRestorerMock(
-                    _fileSystem,
-                    _reporter,
-                    new List<MockFeed>
-                    {
-                        new MockFeed
-                        {
-                            Type = MockFeedType.ImplicitAdditionalFeed,
-                            Packages = new List<MockFeedPackage>
+            _mockFeed = new MockFeed
+            {
+                Type = MockFeedType.ImplicitAdditionalFeed,
+                Packages = new List<MockFeedPackage>
                             {
                                 new MockFeedPackage
                                 {
@@ -73,8 +69,19 @@ public ToolInstallLocalCommandTests()
                                     ToolCommandName = _toolCommandNameA.ToString()
                                 }
                             }
-                        }
-                    }));
+
+            };
+
+            _toolPackageInstallerMock = new ToolPackageInstallerMock(
+                _fileSystem,
+                _toolPackageStore,
+                new ProjectRestorerMock(
+                    _fileSystem,
+                    _reporter,
+                    new List<MockFeed>
+                    {
+                        _mockFeed
+                }));
 
             _localToolsResolverCache
                 = new LocalToolsResolverCache(
@@ -219,7 +226,7 @@ public void GivenManifestFileConflictItShouldNotAddToCache()
                 new FilePath(_manifestFilePath),
                 _packageIdA,
                 new NuGetVersion(1, 1, 1),
-                new[] {_toolCommandNameA});
+                new[] { _toolCommandNameA });
 
             var toolInstallLocalCommand = GetDefaultTestToolInstallLocalCommand();
 
@@ -314,6 +321,154 @@ out RestoredCommand restoredCommand
             _fileSystem.File.Exists(restoredCommand.Executable.Value);
         }
 
+        [Fact]
+        public void GivenFeedVersionIsTheSameWhenRunWithPackageIdItShouldShowDifferentSuccessMessage()
+        {
+            GetDefaultTestToolInstallLocalCommand().Execute().Should().Be(0);
+            _reporter.Clear();
+            GetDefaultTestToolInstallLocalCommand().Execute().Should().Be(0);
+
+            AssertUpdateSuccess(packageVersion: _packageVersionA);
+            _reporter.Lines.Single()
+                .Should().Contain(
+                    string.Format(
+                        Tools.Tool.Update.LocalizableStrings.UpdateLocaToolSucceededVersionNoChange,
+                        _packageIdA,
+                        _packageVersionA.ToNormalizedString(),
+                        _manifestFilePath));
+        }
+
+        [Fact]
+        public void GivenFeedVersionIsLowerRunPackageIdItShouldThrow()
+        {
+            GetDefaultTestToolInstallLocalCommand().Execute().Should().Be(0);
+
+            _mockFeed.Packages.Add(new MockFeedPackage
+            {
+                PackageId = _packageIdA.ToString(),
+                Version = "0.9.0",
+                ToolCommandName = _toolCommandNameA.ToString()
+            });
+
+            _mockFeed.Packages.Add(new MockFeedPackage
+            {
+                PackageId = _packageIdA.ToString(),
+                Version = "1.0.4",
+                ToolCommandName = _toolCommandNameA.ToString()
+            });
+
+            ParseResult result = Parser.Instance.Parse(
+               $"dotnet tool install {_packageIdA.ToString()} --version 0.9.0");
+
+            var installLocalCommand = new ToolInstallLocalCommand(
+                result,
+                _toolPackageInstallerMock,
+                _toolManifestFinder,
+                _toolManifestEditor,
+                _localToolsResolverCache,
+                _reporter);
+
+            _reporter.Clear();
+            Action a = () => installLocalCommand.Execute();
+            a.Should().Throw<GracefulException>().And.Message.Should().Contain(string.Format(
+                Tools.Tool.Update.LocalizableStrings.UpdateLocalToolToLowerVersion,
+                "0.9.0",
+                _packageVersionA.ToNormalizedString(),
+                _manifestFilePath));
+        }
+
+        [Fact]
+        public void GivenFeedVersionIsLowerWithAllowDowngradeOptionRunPackageIdItShouldUpdateToLowerVersion()
+
+        {
+            GetDefaultTestToolInstallLocalCommand().Execute().Should().Be(0);
+
+            _mockFeed.Packages.Add(new MockFeedPackage
+            {
+                PackageId = _packageIdA.ToString(),
+                Version = "0.9.0",
+                ToolCommandName = _toolCommandNameA.ToString()
+            });
+
+            _mockFeed.Packages.Add(new MockFeedPackage
+            {
+                PackageId = _packageIdA.ToString(),
+                Version = "1.0.4",
+                ToolCommandName = _toolCommandNameA.ToString()
+            });
+
+            _reporter.Clear();
+
+            ParseResult result = Parser.Instance.Parse(
+                $"dotnet tool install {_packageIdA.ToString()} --version 0.9.0 --allow-downgrade");
+
+            var installLocalCommand = new ToolInstallLocalCommand(
+                result,
+                _toolPackageInstallerMock,
+                _toolManifestFinder,
+                _toolManifestEditor,
+                _localToolsResolverCache,
+                _reporter);
+
+            installLocalCommand.Execute().Should().Be(0);
+
+            AssertUpdateSuccess(packageVersion: NuGetVersion.Parse("0.9.0"));
+
+            _reporter.Lines[0]
+                .Should().Contain(
+            string.Format(
+                        Tools.Tool.Update.LocalizableStrings.UpdateLocalToolSucceeded,
+                        _packageIdA,
+                        _packageVersionA.ToNormalizedString(),
+                        NuGetVersion.Parse("0.9.0").ToNormalizedString(),
+                        _manifestFilePath));
+        }
+
+        [Fact]
+        public void GivenFeedVersionIsHigherRunPackageIdItShouldUpdateToHigherVersion()
+        {
+            GetDefaultTestToolInstallLocalCommand().Execute().Should().Be(0);
+
+            _mockFeed.Packages.Add(new MockFeedPackage
+            {
+                PackageId = _packageIdA.ToString(),
+                Version = _packageNewVersionA.ToNormalizedString(),
+                ToolCommandName = _toolCommandNameA.ToString()
+            });
+
+            _reporter.Clear();
+            GetDefaultTestToolInstallLocalCommand().Execute().Should().Be(0);
+
+            AssertUpdateSuccess(packageVersion: _packageNewVersionA);
+
+            _reporter.Lines[0]
+                .Should().Contain(
+            string.Format(
+                        Tools.Tool.Update.LocalizableStrings.UpdateLocalToolSucceeded,
+                        _packageIdA,
+                        _packageVersionA.ToNormalizedString(),
+                        _packageNewVersionA.ToNormalizedString(),
+                        _manifestFilePath));
+        }
+        private void AssertUpdateSuccess(FilePath? manifestFile = null, NuGetVersion packageVersion = null)
+        {
+            packageVersion ??= _packageNewVersionA;
+            IReadOnlyCollection<ToolManifestPackage> manifestPackages = _toolManifestFinder.Find(manifestFile);
+            manifestPackages.Should().HaveCount(1);
+            ToolManifestPackage addedPackage = manifestPackages.Single();
+            addedPackage.Version.Should().Be(packageVersion);
+            _localToolsResolverCache.TryLoad(new RestoredCommandIdentifier(
+                    addedPackage.PackageId,
+                    addedPackage.Version,
+                    NuGetFramework.Parse(BundledTargetFramework.GetTargetFrameworkMoniker()),
+                    Constants.AnyRid,
+                    addedPackage.CommandNames.Single()),
+                out RestoredCommand restoredCommand
+            ).Should().BeTrue();
+
+            _fileSystem.File.Exists(restoredCommand.Executable.Value);
+        }
+
         private IToolPackageInstaller GetToolToolPackageInstallerWithPreviewInFeed()
         {
             List<MockFeed> feeds = new List<MockFeed>
diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolUpdateLocalCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolUpdateLocalCommandTests.cs
index e4f277b098b9..f68e16668344 100644
--- a/src/Tests/dotnet.Tests/CommandTests/ToolUpdateLocalCommandTests.cs
+++ b/src/Tests/dotnet.Tests/CommandTests/ToolUpdateLocalCommandTests.cs
@@ -314,7 +314,7 @@ public void GivenFeedVersionIsLowerRunPackageIdItShouldThrow()
             _reporter.Clear();
             Action a = () => _defaultToolUpdateLocalCommand.Execute();
             a.Should().Throw<GracefulException>().And.Message.Should().Contain(string.Format(
-                LocalizableStrings.UpdateLocaToolToLowerVersion,
+                LocalizableStrings.UpdateLocalToolToLowerVersion,
                 "0.9.0",
                 _packageOriginalVersionA.ToNormalizedString(),
                 _manifestFilePath));