diff --git a/doc/source/user_guide/indexing.rst b/doc/source/user_guide/indexing.rst
index 6843dd1eadc81..cac18f5bf39cd 100644
--- a/doc/source/user_guide/indexing.rst
+++ b/doc/source/user_guide/indexing.rst
@@ -1532,12 +1532,8 @@ Setting metadata
 ~~~~~~~~~~~~~~~~
 
 Indexes are "mostly immutable", but it is possible to set and change their
-metadata, like the index ``name`` (or, for ``MultiIndex``, ``levels`` and
-``codes``).
-
-You can use the ``rename``, ``set_names``, ``set_levels``, and ``set_codes``
-to set these attributes directly. They default to returning a copy; however,
-you can specify ``inplace=True`` to have the data change in place.
+``name`` attribute. You can use the ``rename``, ``set_names`` to set these attributes
+directly, and they default to returning a copy.
 
 See :ref:`Advanced Indexing <advanced>` for usage of MultiIndexes.
 
diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst
index 33e70daa55e66..d3bccada09c29 100644
--- a/doc/source/whatsnew/v1.2.0.rst
+++ b/doc/source/whatsnew/v1.2.0.rst
@@ -47,7 +47,7 @@ Other enhancements
 
 Deprecations
 ~~~~~~~~~~~~
-
+- Deprecated parameter ``inplace`` in :meth:`MultiIndex.set_codes` and :meth:`MultiIndex.set_levels` (:issue:`35626`)
 -
 -
 
diff --git a/pandas/conftest.py b/pandas/conftest.py
index e0adb37e7d2f5..c1925b4f5ca3b 100644
--- a/pandas/conftest.py
+++ b/pandas/conftest.py
@@ -359,7 +359,7 @@ def multiindex_year_month_day_dataframe_random_data():
     tdf = tm.makeTimeDataFrame(100)
     ymd = tdf.groupby([lambda x: x.year, lambda x: x.month, lambda x: x.day]).sum()
     # use Int64Index, to make sure things work
-    ymd.index.set_levels([lev.astype("i8") for lev in ymd.index.levels], inplace=True)
+    ymd.index = ymd.index.set_levels([lev.astype("i8") for lev in ymd.index.levels])
     ymd.index.set_names(["year", "month", "day"], inplace=True)
     return ymd
 
diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py
index a6e8ec0707de7..13927dede5542 100644
--- a/pandas/core/indexes/multi.py
+++ b/pandas/core/indexes/multi.py
@@ -740,7 +740,7 @@ def _set_levels(
         self._tuples = None
         self._reset_cache()
 
-    def set_levels(self, levels, level=None, inplace=False, verify_integrity=True):
+    def set_levels(self, levels, level=None, inplace=None, verify_integrity=True):
         """
         Set new levels on MultiIndex. Defaults to returning new index.
 
@@ -752,6 +752,8 @@ def set_levels(self, levels, level=None, inplace=False, verify_integrity=True):
             Level(s) to set (None for all levels).
         inplace : bool
             If True, mutates in place.
+
+            .. deprecated:: 1.2.0
         verify_integrity : bool, default True
             If True, checks that levels and codes are compatible.
 
@@ -822,6 +824,15 @@ def set_levels(self, levels, level=None, inplace=False, verify_integrity=True):
         >>> idx.set_levels([['a', 'b', 'c'], [1, 2, 3, 4]], level=[0, 1]).levels
         FrozenList([['a', 'b', 'c'], [1, 2, 3, 4]])
         """
+        if inplace is not None:
+            warnings.warn(
+                "inplace is deprecated and will be removed in a future version.",
+                FutureWarning,
+                stacklevel=2,
+            )
+        else:
+            inplace = False
+
         if is_list_like(levels) and not isinstance(levels, Index):
             levels = list(levels)
 
@@ -898,7 +909,7 @@ def _set_codes(
         self._tuples = None
         self._reset_cache()
 
-    def set_codes(self, codes, level=None, inplace=False, verify_integrity=True):
+    def set_codes(self, codes, level=None, inplace=None, verify_integrity=True):
         """
         Set new codes on MultiIndex. Defaults to returning new index.
 
@@ -914,6 +925,8 @@ def set_codes(self, codes, level=None, inplace=False, verify_integrity=True):
             Level(s) to set (None for all levels).
         inplace : bool
             If True, mutates in place.
+
+            .. deprecated:: 1.2.0
         verify_integrity : bool (default True)
             If True, checks that levels and codes are compatible.
 
@@ -958,6 +971,15 @@ def set_codes(self, codes, level=None, inplace=False, verify_integrity=True):
                     (1, 'two')],
                    names=['foo', 'bar'])
         """
+        if inplace is not None:
+            warnings.warn(
+                "inplace is deprecated and will be removed in a future version.",
+                FutureWarning,
+                stacklevel=2,
+            )
+        else:
+            inplace = False
+
         if level is not None and not is_list_like(level):
             if not is_list_like(codes):
                 raise TypeError("Codes must be list-like")
diff --git a/pandas/tests/frame/methods/test_sort_index.py b/pandas/tests/frame/methods/test_sort_index.py
index 5216c3be116e0..dcc33428d18a5 100644
--- a/pandas/tests/frame/methods/test_sort_index.py
+++ b/pandas/tests/frame/methods/test_sort_index.py
@@ -555,8 +555,8 @@ def test_sort_index_and_reconstruction(self):
             ),
         )
 
-        df.columns.set_levels(
-            pd.to_datetime(df.columns.levels[1]), level=1, inplace=True
+        df.columns = df.columns.set_levels(
+            pd.to_datetime(df.columns.levels[1]), level=1
         )
         assert not df.columns.is_lexsorted()
         assert not df.columns.is_monotonic
diff --git a/pandas/tests/indexes/multi/test_compat.py b/pandas/tests/indexes/multi/test_compat.py
index d1f66af4a8e83..b2500efef9e03 100644
--- a/pandas/tests/indexes/multi/test_compat.py
+++ b/pandas/tests/indexes/multi/test_compat.py
@@ -84,7 +84,8 @@ def test_inplace_mutation_resets_values():
     tm.assert_almost_equal(mi1.values, vals)
 
     # Inplace should kill _tuples
-    mi1.set_levels(levels2, inplace=True)
+    with tm.assert_produces_warning(FutureWarning):
+        mi1.set_levels(levels2, inplace=True)
     tm.assert_almost_equal(mi1.values, vals2)
 
     # Make sure label setting works too
@@ -103,7 +104,8 @@ def test_inplace_mutation_resets_values():
     tm.assert_almost_equal(exp_values, new_values)
 
     # ...and again setting inplace should kill _tuples, etc
-    mi2.set_codes(codes2, inplace=True)
+    with tm.assert_produces_warning(FutureWarning):
+        mi2.set_codes(codes2, inplace=True)
     tm.assert_almost_equal(mi2.values, new_values)
 
 
diff --git a/pandas/tests/indexes/multi/test_duplicates.py b/pandas/tests/indexes/multi/test_duplicates.py
index e48731b9c8099..9add4b478da47 100644
--- a/pandas/tests/indexes/multi/test_duplicates.py
+++ b/pandas/tests/indexes/multi/test_duplicates.py
@@ -91,7 +91,8 @@ def test_duplicate_multiindex_codes():
     mi = MultiIndex.from_arrays([["A", "A", "B", "B", "B"], [1, 2, 1, 2, 3]])
     msg = r"Level values must be unique: \[[AB', ]+\] on level 0"
     with pytest.raises(ValueError, match=msg):
-        mi.set_levels([["A", "B", "A", "A", "B"], [2, 1, 3, -2, 5]], inplace=True)
+        with tm.assert_produces_warning(FutureWarning):
+            mi.set_levels([["A", "B", "A", "A", "B"], [2, 1, 3, -2, 5]], inplace=True)
 
 
 @pytest.mark.parametrize("names", [["a", "b", "a"], [1, 1, 2], [1, "a", 1]])
diff --git a/pandas/tests/indexes/multi/test_equivalence.py b/pandas/tests/indexes/multi/test_equivalence.py
index 063ede028add7..b48f09457b96c 100644
--- a/pandas/tests/indexes/multi/test_equivalence.py
+++ b/pandas/tests/indexes/multi/test_equivalence.py
@@ -192,10 +192,12 @@ def test_is_():
     mi4 = mi3.view()
 
     # GH 17464 - Remove duplicate MultiIndex levels
-    mi4.set_levels([list(range(10)), list(range(10))], inplace=True)
+    with tm.assert_produces_warning(FutureWarning):
+        mi4.set_levels([list(range(10)), list(range(10))], inplace=True)
     assert not mi4.is_(mi3)
     mi5 = mi.view()
-    mi5.set_levels(mi5.levels, inplace=True)
+    with tm.assert_produces_warning(FutureWarning):
+        mi5.set_levels(mi5.levels, inplace=True)
     assert not mi5.is_(mi)
 
 
diff --git a/pandas/tests/indexes/multi/test_get_set.py b/pandas/tests/indexes/multi/test_get_set.py
index 8a3deca0236e4..b9132f429905d 100644
--- a/pandas/tests/indexes/multi/test_get_set.py
+++ b/pandas/tests/indexes/multi/test_get_set.py
@@ -93,7 +93,8 @@ def test_set_levels(idx):
 
     # level changing [w/ mutation]
     ind2 = idx.copy()
-    inplace_return = ind2.set_levels(new_levels, inplace=True)
+    with tm.assert_produces_warning(FutureWarning):
+        inplace_return = ind2.set_levels(new_levels, inplace=True)
     assert inplace_return is None
     assert_matching(ind2.levels, new_levels)
 
@@ -113,20 +114,23 @@ def test_set_levels(idx):
 
     # level changing specific level [w/ mutation]
     ind2 = idx.copy()
-    inplace_return = ind2.set_levels(new_levels[0], level=0, inplace=True)
+    with tm.assert_produces_warning(FutureWarning):
+        inplace_return = ind2.set_levels(new_levels[0], level=0, inplace=True)
     assert inplace_return is None
     assert_matching(ind2.levels, [new_levels[0], levels[1]])
     assert_matching(idx.levels, levels)
 
     ind2 = idx.copy()
-    inplace_return = ind2.set_levels(new_levels[1], level=1, inplace=True)
+    with tm.assert_produces_warning(FutureWarning):
+        inplace_return = ind2.set_levels(new_levels[1], level=1, inplace=True)
     assert inplace_return is None
     assert_matching(ind2.levels, [levels[0], new_levels[1]])
     assert_matching(idx.levels, levels)
 
     # level changing multiple levels [w/ mutation]
     ind2 = idx.copy()
-    inplace_return = ind2.set_levels(new_levels, level=[0, 1], inplace=True)
+    with tm.assert_produces_warning(FutureWarning):
+        inplace_return = ind2.set_levels(new_levels, level=[0, 1], inplace=True)
     assert inplace_return is None
     assert_matching(ind2.levels, new_levels)
     assert_matching(idx.levels, levels)
@@ -136,19 +140,23 @@ def test_set_levels(idx):
     original_index = idx.copy()
     for inplace in [True, False]:
         with pytest.raises(ValueError, match="^On"):
-            idx.set_levels(["c"], level=0, inplace=inplace)
+            with tm.assert_produces_warning(FutureWarning):
+                idx.set_levels(["c"], level=0, inplace=inplace)
         assert_matching(idx.levels, original_index.levels, check_dtype=True)
 
         with pytest.raises(ValueError, match="^On"):
-            idx.set_codes([0, 1, 2, 3, 4, 5], level=0, inplace=inplace)
+            with tm.assert_produces_warning(FutureWarning):
+                idx.set_codes([0, 1, 2, 3, 4, 5], level=0, inplace=inplace)
         assert_matching(idx.codes, original_index.codes, check_dtype=True)
 
         with pytest.raises(TypeError, match="^Levels"):
-            idx.set_levels("c", level=0, inplace=inplace)
+            with tm.assert_produces_warning(FutureWarning):
+                idx.set_levels("c", level=0, inplace=inplace)
         assert_matching(idx.levels, original_index.levels, check_dtype=True)
 
         with pytest.raises(TypeError, match="^Codes"):
-            idx.set_codes(1, level=0, inplace=inplace)
+            with tm.assert_produces_warning(FutureWarning):
+                idx.set_codes(1, level=0, inplace=inplace)
         assert_matching(idx.codes, original_index.codes, check_dtype=True)
 
 
@@ -168,7 +176,8 @@ def test_set_codes(idx):
 
     # changing label w/ mutation
     ind2 = idx.copy()
-    inplace_return = ind2.set_codes(new_codes, inplace=True)
+    with tm.assert_produces_warning(FutureWarning):
+        inplace_return = ind2.set_codes(new_codes, inplace=True)
     assert inplace_return is None
     assert_matching(ind2.codes, new_codes)
 
@@ -188,20 +197,23 @@ def test_set_codes(idx):
 
     # label changing specific level w/ mutation
     ind2 = idx.copy()
-    inplace_return = ind2.set_codes(new_codes[0], level=0, inplace=True)
+    with tm.assert_produces_warning(FutureWarning):
+        inplace_return = ind2.set_codes(new_codes[0], level=0, inplace=True)
     assert inplace_return is None
     assert_matching(ind2.codes, [new_codes[0], codes[1]])
     assert_matching(idx.codes, codes)
 
     ind2 = idx.copy()
-    inplace_return = ind2.set_codes(new_codes[1], level=1, inplace=True)
+    with tm.assert_produces_warning(FutureWarning):
+        inplace_return = ind2.set_codes(new_codes[1], level=1, inplace=True)
     assert inplace_return is None
     assert_matching(ind2.codes, [codes[0], new_codes[1]])
     assert_matching(idx.codes, codes)
 
     # codes changing multiple levels [w/ mutation]
     ind2 = idx.copy()
-    inplace_return = ind2.set_codes(new_codes, level=[0, 1], inplace=True)
+    with tm.assert_produces_warning(FutureWarning):
+        inplace_return = ind2.set_codes(new_codes, level=[0, 1], inplace=True)
     assert inplace_return is None
     assert_matching(ind2.codes, new_codes)
     assert_matching(idx.codes, codes)
@@ -217,7 +229,8 @@ def test_set_codes(idx):
 
     # [w/ mutation]
     result = ind.copy()
-    result.set_codes(codes=new_codes, level=1, inplace=True)
+    with tm.assert_produces_warning(FutureWarning):
+        result.set_codes(codes=new_codes, level=1, inplace=True)
     assert result.equals(expected)
 
 
@@ -329,3 +342,19 @@ def test_set_levels_with_iterable():
         [expected_sizes, colors], names=["size", "color"]
     )
     tm.assert_index_equal(result, expected)
+
+
+@pytest.mark.parametrize("inplace", [True, False])
+def test_set_codes_inplace_deprecated(idx, inplace):
+    new_codes = idx.codes[1][::-1]
+
+    with tm.assert_produces_warning(FutureWarning):
+        idx.set_codes(codes=new_codes, level=1, inplace=inplace)
+
+
+@pytest.mark.parametrize("inplace", [True, False])
+def test_set_levels_inplace_deprecated(idx, inplace):
+    new_level = idx.levels[1].copy()
+
+    with tm.assert_produces_warning(FutureWarning):
+        idx.set_levels(levels=new_level, level=1, inplace=inplace)
diff --git a/pandas/tests/indexes/multi/test_integrity.py b/pandas/tests/indexes/multi/test_integrity.py
index fd150bb4d57a2..c776a33717ccd 100644
--- a/pandas/tests/indexes/multi/test_integrity.py
+++ b/pandas/tests/indexes/multi/test_integrity.py
@@ -220,7 +220,8 @@ def test_metadata_immutable(idx):
 def test_level_setting_resets_attributes():
     ind = pd.MultiIndex.from_arrays([["A", "A", "B", "B", "B"], [1, 2, 1, 2, 3]])
     assert ind.is_monotonic
-    ind.set_levels([["A", "B"], [1, 3, 2]], inplace=True)
+    with tm.assert_produces_warning(FutureWarning):
+        ind.set_levels([["A", "B"], [1, 3, 2]], inplace=True)
     # if this fails, probably didn't reset the cache correctly.
     assert not ind.is_monotonic
 
diff --git a/pandas/tests/indexing/multiindex/test_sorted.py b/pandas/tests/indexing/multiindex/test_sorted.py
index 572cb9da405d1..bafe5068e1418 100644
--- a/pandas/tests/indexing/multiindex/test_sorted.py
+++ b/pandas/tests/indexing/multiindex/test_sorted.py
@@ -43,9 +43,13 @@ def test_frame_getitem_not_sorted2(self, key):
         df2 = df.set_index(["col1", "col2"])
         df2_original = df2.copy()
 
-        return_value = df2.index.set_levels(["b", "d", "a"], level="col1", inplace=True)
+        with tm.assert_produces_warning(FutureWarning):
+            return_value = df2.index.set_levels(
+                ["b", "d", "a"], level="col1", inplace=True
+            )
         assert return_value is None
-        return_value = df2.index.set_codes([0, 1, 0, 2], level="col1", inplace=True)
+        with tm.assert_produces_warning(FutureWarning):
+            return_value = df2.index.set_codes([0, 1, 0, 2], level="col1", inplace=True)
         assert return_value is None
         assert not df2.index.is_lexsorted()
         assert not df2.index.is_monotonic
diff --git a/pandas/tests/reshape/test_melt.py b/pandas/tests/reshape/test_melt.py
index 2b75a1ec6ca6e..79879ef346f53 100644
--- a/pandas/tests/reshape/test_melt.py
+++ b/pandas/tests/reshape/test_melt.py
@@ -799,7 +799,7 @@ def test_invalid_separator(self):
         expected = expected.set_index(["id", "year"])[
             ["X", "A2010", "A2011", "B2010", "A", "B"]
         ]
-        expected.index.set_levels([0, 1], level=0, inplace=True)
+        expected.index = expected.index.set_levels([0, 1], level=0)
         result = wide_to_long(df, ["A", "B"], i="id", j="year", sep=sep)
         tm.assert_frame_equal(result.sort_index(axis=1), expected.sort_index(axis=1))
 
@@ -861,7 +861,7 @@ def test_invalid_suffixtype(self):
         expected = pd.DataFrame(exp_data).astype({"year": "int"})
 
         expected = expected.set_index(["id", "year"])
-        expected.index.set_levels([0, 1], level=0, inplace=True)
+        expected.index = expected.index.set_levels([0, 1], level=0)
         result = wide_to_long(df, ["A", "B"], i="id", j="year")
         tm.assert_frame_equal(result.sort_index(axis=1), expected.sort_index(axis=1))
 
diff --git a/pandas/tests/test_multilevel.py b/pandas/tests/test_multilevel.py
index 1ba73292dc0b4..724558bd49ea2 100644
--- a/pandas/tests/test_multilevel.py
+++ b/pandas/tests/test_multilevel.py
@@ -63,8 +63,8 @@ def setup_method(self, method):
         ).sum()
 
         # use Int64Index, to make sure things work
-        self.ymd.index.set_levels(
-            [lev.astype("i8") for lev in self.ymd.index.levels], inplace=True
+        self.ymd.index = self.ymd.index.set_levels(
+            [lev.astype("i8") for lev in self.ymd.index.levels]
         )
         self.ymd.index.set_names(["year", "month", "day"], inplace=True)