diff --git a/src/libraries/System.Runtime.Numerics/src/Properties/InternalsVisibleTo.cs b/src/libraries/System.Runtime.Numerics/src/Properties/InternalsVisibleTo.cs
new file mode 100644
index 00000000000000..37afaaf1abfac7
--- /dev/null
+++ b/src/libraries/System.Runtime.Numerics/src/Properties/InternalsVisibleTo.cs
@@ -0,0 +1,6 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Runtime.CompilerServices;
+
+[assembly: InternalsVisibleTo("System.Runtime.Numerics.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001004b86c4cb78549b34bab61a3b1800e23bfeb5b3ec390074041536a7e3cbd97f5f04cf0f857155a8928eaa29ebfd11cfbbad3ba70efea7bda3226c6a8d370a4cd303f714486b6ebc225985a638471e6ef571cc92a4613c00b8fa65d61ccee0cbe5f36330c9a01f4183559f1bef24cc2917c6d913e3a541333a1d05d9bed22b38cb")]
diff --git a/src/libraries/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj b/src/libraries/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj
index 5c2f63834c360d..1de04876ac55a3 100644
--- a/src/libraries/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj
+++ b/src/libraries/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj
@@ -25,6 +25,7 @@
              Link="CoreLib\System\Text\ValueStringBuilder.cs" />
     <Compile Include="$(CommonPath)System\HexConverter.cs"
              Link="Common\System\HexConverter.cs" />
+    <Compile Include="Properties\InternalsVisibleTo.cs" />
   </ItemGroup>
   <ItemGroup>
     <Reference Include="System.Memory" />
diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
index 1546c4efbc65f8..804575ec3cd7a6 100644
--- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
+++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
@@ -2204,7 +2204,7 @@ stackalloc uint[BigIntegerCalculator.StackAllocThreshold]
 
             if (negx)
             {
-                if (shift >= (kcbitUint * xd.Length))
+                if (shift >= ((long)kcbitUint * xd.Length))
                 {
                     result = MinusOne;
                     goto exit;
diff --git a/src/libraries/System.Runtime.Numerics/tests/BigInteger/op_rightshift.cs b/src/libraries/System.Runtime.Numerics/tests/BigInteger/op_rightshift.cs
index 2f65e779c0430f..da6ac2615b9c1b 100644
--- a/src/libraries/System.Runtime.Numerics/tests/BigInteger/op_rightshift.cs
+++ b/src/libraries/System.Runtime.Numerics/tests/BigInteger/op_rightshift.cs
@@ -25,6 +25,54 @@ public static void BigShiftsTest()
             }
         }
 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] // May fail on 32-bit due to a large memory requirement
+        public static void LargeNegativeBigIntegerShiftTest()
+        {
+            // Create a very large negative BigInteger
+            BigInteger bigInt = new BigInteger(-1) << int.MaxValue;
+            Assert.Equal(2147483647, bigInt.GetBitLength());
+            Assert.Equal(-1, bigInt.Sign);
+
+            // Validate internal representation.
+            // At this point, bigInt should be a 1 followed by int.MaxValue zeros.
+            // Given this, bigInt._bits is expected to be structured as follows:
+            // - _bits.Length == (int.MaxValue + 1) / (8 * sizeof(uint))
+            // - First (_bits.Length - 1) elements: 0x00000000
+            // - Last element: 0x80000000
+            //                   ^------ (There's the leading '1')
+
+            Assert.Equal(((uint)int.MaxValue + 1) / (8 * sizeof(uint)), (uint)bigInt._bits.Length);
+
+            uint i = 0;
+            for (; i < (bigInt._bits.Length - 1); i++) {
+                Assert.Equal(0x00000000u, bigInt._bits[i]);
+            }
+
+            Assert.Equal(0x80000000u, bigInt._bits[i]);
+
+            // Right shift the BigInteger
+            BigInteger shiftedBigInt = bigInt >> 1;
+            Assert.Equal(2147483646, shiftedBigInt.GetBitLength());
+            Assert.Equal(-1, shiftedBigInt.Sign);
+
+            // Validate internal representation.
+            // At this point, shiftedBigInt should be a 1 followed by int.MaxValue - 1 zeros.
+            // Given this, shiftedBigInt._bits is expected to be structured as follows:
+            // - _bits.Length == (int.MaxValue + 1) / (8 * sizeof(uint))
+            // - First (_bits.Length - 1) elements: 0x00000000
+            // - Last element: 0x40000000
+            //                   ^------ (the '1' is now one position to the right)
+
+            Assert.Equal(((uint)int.MaxValue + 1) / (8 * sizeof(uint)), (uint)shiftedBigInt._bits.Length);
+
+            i = 0;
+            for (; i < (shiftedBigInt._bits.Length - 1); i++) {
+                Assert.Equal(0x00000000u, shiftedBigInt._bits[i]);
+            }
+
+            Assert.Equal(0x40000000u, shiftedBigInt._bits[i]);
+        }
+
         [Fact]
         public static void RunRightShiftTests()
         {
diff --git a/src/libraries/System.Runtime.Numerics/tests/System.Runtime.Numerics.Tests.csproj b/src/libraries/System.Runtime.Numerics/tests/System.Runtime.Numerics.Tests.csproj
index 3cd75b812f1eb6..4b9dbea05bf6b0 100644
--- a/src/libraries/System.Runtime.Numerics/tests/System.Runtime.Numerics.Tests.csproj
+++ b/src/libraries/System.Runtime.Numerics/tests/System.Runtime.Numerics.Tests.csproj
@@ -54,4 +54,8 @@
     <Compile Include="BigInteger\TryWriteBytes.cs" />
     <Compile Include="ComplexTests.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <!-- Some internal types are needed, so we reference the implementation assembly, rather than the reference assembly. -->
+    <ProjectReference Include="..\src\System.Runtime.Numerics.csproj" SkipUseReferenceAssembly="true" />
+  </ItemGroup>
 </Project>