diff --git a/typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbBackend.php b/typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbBackend.php
index 8fa24f2333..bce272da41 100644
--- a/typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbBackend.php
+++ b/typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbBackend.php
@@ -650,7 +650,12 @@ class Typo3DbBackend implements BackendInterface, SingletonInterface
             ) {
                 if (in_array($row[$GLOBALS['TCA'][$tableName]['ctrl']['languageField']], [-1, 0])) {
                     $overlayMode = $querySettings->getLanguageMode() === 'strict' ? 'hideNonTranslated' : '';
-                    $row = $pageRepository->getRecordOverlay($tableName, $row, $querySettings->getLanguageUid(), $overlayMode);
+                    $row = $pageRepository->getRecordOverlayWithFallback(
+                        $tableName,
+                        $row,
+                        $querySettings->getLanguageUid(),
+                        $overlayMode
+                    );
                 }
             }
             if ($row !== null && is_array($row)) {
diff --git a/typo3/sysext/frontend/Classes/Aspect/FileMetadataOverlayAspect.php b/typo3/sysext/frontend/Classes/Aspect/FileMetadataOverlayAspect.php
index d9614fdfb7..681c0b73f3 100644
--- a/typo3/sysext/frontend/Classes/Aspect/FileMetadataOverlayAspect.php
+++ b/typo3/sysext/frontend/Classes/Aspect/FileMetadataOverlayAspect.php
@@ -35,11 +35,9 @@ class FileMetadataOverlayAspect
     {
         $overlaidMetaData = $data->getArrayCopy();
         $this->getTsfe()->sys_page->versionOL('sys_file_metadata', $overlaidMetaData);
-        $overlaidMetaData = $this->getTsfe()->sys_page->getRecordOverlay(
+        $overlaidMetaData = $this->getTsfe()->sys_page->getRecordOverlayWithFallback(
             'sys_file_metadata',
-            $overlaidMetaData,
-            $this->getTsfe()->sys_language_content,
-            $this->getTsfe()->sys_language_contentOL
+            $overlaidMetaData
         );
         if ($overlaidMetaData !== null) {
             $data->exchangeArray($overlaidMetaData);
diff --git a/typo3/sysext/frontend/Classes/Category/Collection/CategoryCollection.php b/typo3/sysext/frontend/Classes/Category/Collection/CategoryCollection.php
index f325e58a94..8d2d53319a 100644
--- a/typo3/sysext/frontend/Classes/Category/Collection/CategoryCollection.php
+++ b/typo3/sysext/frontend/Classes/Category/Collection/CategoryCollection.php
@@ -162,11 +162,9 @@ class CategoryCollection extends \TYPO3\CMS\Core\Category\Collection\CategoryCol
                 if ($this->getItemTableName() === 'pages') {
                     $record = $tsfe->sys_page->getPageOverlay($record);
                 } else {
-                    $record = $tsfe->sys_page->getRecordOverlay(
+                    $record = $this->getFrontendObject()->sys_page->getRecordOverlayWithFallback(
                         $this->getItemTableName(),
-                        $record,
-                        $tsfe->sys_language_content,
-                        $tsfe->sys_language_contentOL
+                        $record
                     );
                 }
             }
diff --git a/typo3/sysext/frontend/Classes/ContentObject/FilesContentObject.php b/typo3/sysext/frontend/Classes/ContentObject/FilesContentObject.php
index 823aa3a1ba..907573f213 100644
--- a/typo3/sysext/frontend/Classes/ContentObject/FilesContentObject.php
+++ b/typo3/sysext/frontend/Classes/ContentObject/FilesContentObject.php
@@ -197,12 +197,7 @@ class FilesContentObject extends AbstractContentObject
             if ($referencesForeignTable === 'pages') {
                 $element = $pageRepository->getPageOverlay($element);
             } else {
-                $element = $pageRepository->getRecordOverlay(
-                    $referencesForeignTable,
-                    $element,
-                    $GLOBALS['TSFE']->sys_language_content,
-                    $GLOBALS['TSFE']->sys_language_contentOL
-                );
+                $element = $pageRepository->getRecordOverlayWithFallback($referencesForeignTable, $element);
             }
         }
 
diff --git a/typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php b/typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php
index ad809e2de5..4d6abe6479 100644
--- a/typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php
+++ b/typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php
@@ -1283,7 +1283,7 @@ abstract class AbstractMenuContentObject
                 $tok = true;
                 // There is an alternative language active AND the current page requires a translation:
                 if ($tsfe->sys_language_uid && GeneralUtility::hideIfNotTranslated($data['l18n_cfg'])) {
-                    if (!$data['_PAGES_OVERLAY']) {
+                    if (!$data['_PAGES_OVERLAY'] || (int)$data['sys_language_uid'] !== (int)$GLOBALS['TSFE']->sys_language_uid) {
                         $tok = false;
                     }
                 }
@@ -2226,7 +2226,7 @@ abstract class AbstractMenuContentObject
         while ($row = $statement->fetch()) {
             $this->sys_page->versionOL('tt_content', $row);
             if ($tsfe->sys_language_contentOL && $basePageRow['_PAGES_OVERLAY_LANGUAGE']) {
-                $row = $this->sys_page->getRecordOverlay('tt_content', $row, $basePageRow['_PAGES_OVERLAY_LANGUAGE'], $tsfe->sys_language_contentOL);
+                $row = $this->sys_page->getRecordOverlayWithFallback('tt_content', $row, $basePageRow['_PAGES_OVERLAY_LANGUAGE']);
             }
             if ($this->mconf['sectionIndex.']['type'] !== 'all') {
                 $doIncludeInSectionIndex = $row['sectionIndex'] >= 1;
diff --git a/typo3/sysext/frontend/Classes/ContentObject/RecordsContentObject.php b/typo3/sysext/frontend/Classes/ContentObject/RecordsContentObject.php
index 6140213aeb..7a200bca45 100644
--- a/typo3/sysext/frontend/Classes/ContentObject/RecordsContentObject.php
+++ b/typo3/sysext/frontend/Classes/ContentObject/RecordsContentObject.php
@@ -49,13 +49,14 @@ class RecordsContentObject extends AbstractContentObject
         // Reset items and data
         $this->itemArray = [];
         $this->data = [];
+        $tsfe = $this->getTypoScriptFrontendController();
 
         $theValue = '';
-        $originalRec = $GLOBALS['TSFE']->currentRecord;
+        $originalRec = $tsfe->currentRecord;
         // If the currentRecord is set, we register, that this record has invoked this function.
         // It's should not be allowed to do this again then!!
         if ($originalRec) {
-            ++$GLOBALS['TSFE']->recordRegister[$originalRec];
+            ++$tsfe->recordRegister[$originalRec];
         }
 
         $tables = isset($conf['tables.']) ? $this->cObj->stdWrap($conf['tables'], $conf['tables.']) : $conf['tables'];
@@ -92,13 +93,22 @@ class RecordsContentObject extends AbstractContentObject
                     // Perform overlays if necessary (records coming from category collections are already overlaid)
                     if ($source) {
                         // Versioning preview
-                        $GLOBALS['TSFE']->sys_page->versionOL($val['table'], $row);
+                        $tsfe->sys_page->versionOL($val['table'], $row);
                         // Language overlay
-                        if (is_array($row) && $GLOBALS['TSFE']->sys_language_contentOL) {
+                        if (is_array($row) && $tsfe->sys_language_contentOL) {
                             if ($val['table'] === 'pages') {
-                                $row = $GLOBALS['TSFE']->sys_page->getPageOverlay($row);
+                                $row = $tsfe->sys_page->getPageOverlay($row);
                             } else {
-                                $row = $GLOBALS['TSFE']->sys_page->getRecordOverlay($val['table'], $row, $GLOBALS['TSFE']->sys_language_content, $GLOBALS['TSFE']->sys_language_contentOL);
+                                $fallbackChain = NULL;
+                                if (isset($conf['languageFallbackChain'])) {
+                                    $fallbackChain = GeneralUtility::intExplode(',', $conf['languageFallbackChain']);
+                                }
+
+                                $pageLanguageBinding = !isset($conf['respectPageLanguageBinding']) || (int)$conf['respectPageLanguageBinding'] !== '0';
+
+                                $row = $tsfe->sys_page->getRecordOverlayWithFallback(
+                                    $val['table'], $row, NULL, NULL, $fallbackChain, $pageLanguageBinding
+                                );
                             }
                         }
                     }
@@ -108,13 +118,13 @@ class RecordsContentObject extends AbstractContentObject
                         if (!$dontCheckPid) {
                             $row = $this->cObj->checkPid($row['pid']) ? $row : '';
                         }
-                        if ($row && !$GLOBALS['TSFE']->recordRegister[$val['table'] . ':' . $val['id']]) {
+                        if ($row && !$tsfe->recordRegister[($val['table'] . ':' . $val['id'])]) {
                             $renderObjName = $conf['conf.'][$val['table']] ?: '<' . $val['table'];
                             $renderObjKey = $conf['conf.'][$val['table']] ? 'conf.' . $val['table'] : '';
                             $renderObjConf = $conf['conf.'][$val['table'] . '.'];
                             $this->cObj->currentRecordNumber++;
                             $cObj->parentRecordNumber = $this->cObj->currentRecordNumber;
-                            $GLOBALS['TSFE']->currentRecord = $val['table'] . ':' . $val['id'];
+                            $tsfe->currentRecord = $val['table'] . ':' . $val['id'];
                             $this->cObj->lastChanged($row['tstamp']);
                             $cObj->start($row, $val['table']);
                             $tmpValue = $cObj->cObjGetSingle($renderObjName, $renderObjConf, $renderObjKey);
@@ -132,7 +142,7 @@ class RecordsContentObject extends AbstractContentObject
             $theValue = $this->cObj->stdWrap($theValue, $conf['stdWrap.']);
         }
         // Restore
-        $GLOBALS['TSFE']->currentRecord = $originalRec;
+        $tsfe->currentRecord = $originalRec;
         if ($originalRec) {
             --$GLOBALS['TSFE']->recordRegister[$originalRec];
         }
@@ -230,4 +240,11 @@ class RecordsContentObject extends AbstractContentObject
     {
         return GeneralUtility::makeInstance(TimeTracker::class);
     }
+
+    /**
+     * @return \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
+     */
+    protected function getTypoScriptFrontendController() {
+        return $GLOBALS['TSFE'];
+    }
 }
diff --git a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
index 645762f679..f9dc29be4d 100644
--- a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
+++ b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
@@ -574,6 +574,20 @@ class TypoScriptFrontendController
      */
     public $sys_language_content = 0;
 
+    /**
+     * Contains the prioritized language fallback chain
+     *
+     * @var array
+     */
+    public $languageFallbackChain = [];
+
+    /**
+     * Contains the prioritized language fallback chain for the current page
+     *
+     * @var array
+     */
+    public $languageFallbackChainWithPageLanguageBinding = [];
+
     /**
      * Site content overlay flag; If set - and sys_language_content is > 0 - ,
      * records selected will try to look for a translation pointing to their uid. (If
@@ -2590,6 +2604,7 @@ class TypoScriptFrontendController
         // Get values from TypoScript:
         $this->sys_language_uid = ($this->sys_language_content = (int)$this->config['config']['sys_language_uid']);
         list($this->sys_language_mode, $sys_language_content) = GeneralUtility::trimExplode(';', $this->config['config']['sys_language_mode']);
+        $languageFallbackChain = GeneralUtility::intExplode(',', $this->config['config']['languageFallbackChain']);
         $this->sys_language_contentOL = $this->config['config']['sys_language_overlay'];
         // If sys_language_uid is set to another language than default:
         if ($this->sys_language_uid > 0) {
@@ -2611,23 +2626,24 @@ class TypoScriptFrontendController
                                 $this->pageNotFoundAndExit('Page is not available in the requested language (strict).');
                                 break;
                             case 'content_fallback':
-                                // Setting content uid (but leaving the sys_language_uid) when a content_fallback
-                                // value was found.
-                                $fallBackOrder = GeneralUtility::trimExplode(',', $sys_language_content);
-                                foreach ($fallBackOrder as $orderValue) {
-                                    if ($orderValue === '0' || $orderValue === '') {
-                                        $this->sys_language_content = 0;
+                                // default is to fallback to default language
+                                $this->sys_language_content = 0;
+                                foreach ($languageFallbackChain as $languageId) {
+                                    // break the language chain if the current language is selected
+                                    if ($languageId === 0) {
                                         break;
                                     }
-                                    if (MathUtility::canBeInterpretedAsInteger($orderValue) && !empty($this->sys_page->getPageOverlay($this->id, (int)$orderValue))) {
-                                        $this->sys_language_content = (int)$orderValue;
-                                        break;
+                                    // ignore current and invalid language ids
+                                    if ($this->sys_language_uid === $languageId || $languageId < 0) {
+                                        continue;
                                     }
-                                    if ($orderValue === 'pageNotFound') {
-                                        // The existing fallbacks have not been found, but instead of continuing
-                                        // page rendering with default language, a "page not found" message should be shown
-                                        // instead.
-                                        $this->pageNotFoundAndExit('Page is not available in the requested language (fallbacks did not apply).');
+                                    $pageOverlay = $this->sys_page->getPageOverlay($this->id, $languageId);
+                                    if (!empty($pageOverlay)) {
+                                        // Setting content uid (but leaving the sys_language_uid)
+                                        $this->sys_language_content = $languageId;
+                                        // overlay page with existing page overlay
+                                        $this->page = array_merge($this->page, $pageOverlay);
+                                        break;
                                     }
                                 }
                                 break;
@@ -2641,14 +2657,27 @@ class TypoScriptFrontendController
                     }
                 }
             } else {
-                // Setting sys_language if an overlay record was found (which it is only if a language is used)
-                $this->page = $this->sys_page->getPageOverlay($this->page, $this->sys_language_uid);
+                // overlay page with existing page overlay
+                $this->page = array_merge($this->page, $olRec);
+            }
+            // calculate the language fallback chains
+            if ($this->sys_language_mode === 'content_fallback') {
+                foreach ($languageFallbackChain as $languageId) {
+                    // ignore current and invalid language ids
+                    if ($this->sys_language_uid === $languageId || $languageId < 0) {
+                        continue;
+                    }
+                    $this->languageFallbackChain[] = $languageId;
+                    if ($languageId === 0 || count($this->sys_page->getPageOverlay($this->id, $languageId))) {
+                        $this->languageFallbackChainWithPageLanguageBinding[] = $languageId;
+                    }
+                }
             }
         }
         // Setting sys_language_uid inside sys-page:
         $this->sys_page->sys_language_uid = $this->sys_language_uid;
-        // If default translation is not available:
-        if ((!$this->sys_language_uid || !$this->sys_language_content) && GeneralUtility::hideIfDefaultLanguage($this->page['l18n_cfg'])) {
+        // If default translation is not to be selected
+        if ($this->page['l18n_cfg']&1 && !($this->sys_language_uid && $this->sys_language_content)) {
             $message = 'Page is not available in default language.';
             GeneralUtility::sysLog($message, 'cms', GeneralUtility::SYSLOG_SEVERITY_ERROR);
             $this->pageNotFoundAndExit($message);
diff --git a/typo3/sysext/frontend/Classes/Page/PageRepository.php b/typo3/sysext/frontend/Classes/Page/PageRepository.php
index 926e7b18c5..06b4aeeb59 100644
--- a/typo3/sysext/frontend/Classes/Page/PageRepository.php
+++ b/typo3/sysext/frontend/Classes/Page/PageRepository.php
@@ -28,6 +28,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\HttpUtility;
 use TYPO3\CMS\Core\Utility\RootlineUtility;
 use TYPO3\CMS\Core\Versioning\VersionState;
+use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
 
 /**
  * Page functions, a lot of sql/pages-related functions
@@ -430,7 +431,9 @@ class PageRepository
             return [];
         }
         // Initialize:
+        $noSpecialLanguageRequested = false;
         if ($lUid < 0) {
+            $noSpecialLanguageRequested = true;
             $lUid = $this->sys_language_uid;
         }
         $row = null;
@@ -460,6 +463,16 @@ class PageRepository
                     $page_ids[] = $origPage;
                 }
             }
+
+            $languages = [$lUid];
+            if ($noSpecialLanguageRequested) {
+                $languages = array_unique(array_merge(
+                    [$lUid],
+                    $this->getTypoScriptFrontendController()->languageFallbackChain,
+                    [$this->getTypoScriptFrontendController()->sys_language_content]
+                ));
+            }
+
             // NOTE regarding the query restrictions
             // Currently the showHiddenRecords of TSFE set will allow
             // pages_language_overlay records to be selected as they are
@@ -477,9 +490,9 @@ class PageRepository
                         'pid',
                         $queryBuilder->createNamedParameter($page_ids, Connection::PARAM_INT_ARRAY)
                     ),
-                    $queryBuilder->expr()->eq(
+                    $queryBuilder->expr()->in(
                         'sys_language_uid',
-                        $queryBuilder->createNamedParameter($lUid, \PDO::PARAM_INT)
+                        $queryBuilder->createNamedParameter($languages, Connection::PARAM_INT_ARRAY)
                     )
                 )
                 ->execute();
@@ -522,17 +535,70 @@ class PageRepository
     }
 
     /**
-     * Creates language-overlay for records in general (where translation is found
-     * in records from the same table)
+     * Creates a language overlay for records stored inside tables which contain the
+     * translation information themselves. In addition to getRecordOverlay this method
+     * also checks for specified content language fallbacks and includes them.
      *
      * @param string $table Table name
-     * @param array $row Record to overlay. Must contain uid, pid and $table]['ctrl']['languageField']
+     * @param array $row Record to overlay. Must containt uid, pid and $table]['ctrl']['languageField']
      * @param int $sys_language_content Pointer to the sys_language uid for content on the site.
      * @param string $OLmode Overlay mode. If "hideNonTranslated" then records without translation will not be returned  un-translated but unset (and return value is FALSE)
+     * @param array|NULL $fallbackList ordered fallback list of language ids
+     * @param bool $pageLanguageBinding use page language binding for the language fallback chain (only used if fallbackList is NULL)
+     * @return mixed Returns the input record, possibly overlaid with a translation. But if $OLmode is "hideNonTranslated" then it will return NULL if no translation is found.
      * @throws \UnexpectedValueException
-     * @return mixed Returns the input record, possibly overlaid with a translation.  But if $OLmode is "hideNonTranslated" then it will return FALSE if no translation is found.
      */
-    public function getRecordOverlay($table, $row, $sys_language_content, $OLmode = '')
+    public function getRecordOverlayWithFallback(
+        $table,
+        $row,
+        $sys_language_content = null,
+        $OLmode = null,
+        $fallbackList = null,
+        $pageLanguageBinding = true
+    ) {
+        $tsfe = $this->getTypoScriptFrontendController();
+        $sys_language_content = $sys_language_content !== null ? $sys_language_content : $tsfe->sys_language_content;
+        $OLmode = $OLmode !== null ? $OLmode: $tsfe->sys_language_contentOL;
+        if ($fallbackList === null) {
+            $fallbackList = $tsfe->languageFallbackChainWithPageLanguageBinding;
+            if (!$pageLanguageBinding) {
+                $fallbackList = $tsfe->languageFallbackChain;
+            }
+        }
+
+        $record = $this->getRecordOverlayWithoutFallback($table, $row, $sys_language_content, $OLmode);
+        if (!is_array($record) || !isset($record['_LOCALIZED_UID'])) {
+            if ($sys_language_content && $OLmode !== 'hideNonTranslated' && !empty($fallbackList)) {
+                foreach ($fallbackList as $fallbackId) {
+                    $fallbackId = (int)$fallbackId;
+                    if ($fallbackId === 0) {
+                        break;
+                    }
+
+                    $record = $this->getRecordOverlayWithoutFallback($table, $row, $fallbackId, $OLmode);
+                    if (isset($record['_LOCALIZED_UID']) && is_array($record)) {
+                        break;
+                    }
+                }
+            }
+        }
+        return $record;
+    }
+
+    /**
+     * Creates a language overlay for records stored inside tables which contain the
+     * translation information themselves.
+     *
+     *
+     * @param string $table Table name the record comes from
+     * @param array $row Record to overlay. Must contain the columns uid, pid and $TCA[$table]['ctrl']['languageField']
+     * @param int $sys_language_content Pointer to the sys_language uid to use for content.
+     * @param string $OLmode Overlay mode. If "hideNonTranslated" then records without translation will not be returned translated but unset (and return value is FALSE)
+     * @throws \InvalidArgumentException
+     * @throws \UnexpectedValueException
+     * @return mixed Returns the input record, possibly overlaid with a translation. But if $OLmode is "hideNonTranslated" then it will return NULL if no translation is found.
+     */
+    public function getRecordOverlayWithoutFallback($table, $row, $sys_language_content, $OLmode = '')
     {
         if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'])) {
             foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'] as $classRef) {
@@ -629,6 +695,111 @@ class PageRepository
         return $row;
     }
 
+    /**
+     * Creates a language overlay for records stored inside tables which contain the
+     * translation information themselves.
+     *
+     *
+     * @param string $table Table name the record comes from
+     * @param array $row Record to overlay. Must contain the columns uid, pid and $TCA[$table]['ctrl']['languageField']
+     * @param int $sys_language_content Pointer to the sys_language uid to use for content.
+     * @param string $OLmode Overlay mode. If "hideNonTranslated" then records without translation will not be returned translated but unset (and return value is FALSE)
+     * @throws \InvalidArgumentException
+     * @throws \UnexpectedValueException
+     * @return mixed Returns the input record, possibly overlaid with a translation. But if $OLmode is "hideNonTranslated" then it will return NULL if no translation is found.
+     */
+    public function getRecordOverlayWithoutFallback2($table, $row, $sys_language_content, $OLmode) {
+        if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'])) {
+            foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'] as $classRef) {
+                $hookObject = GeneralUtility::getUserObj($classRef);
+                if (!$hookObject instanceof PageRepositoryGetRecordOverlayHookInterface) {
+                    throw new \UnexpectedValueException('$hookObject must implement interface ' . PageRepositoryGetRecordOverlayHookInterface::class, 1269881658);
+                }
+                $hookObject->getRecordOverlay_preProcess($table, $row, $sys_language_content, $OLmode, $this);
+            }
+        }
+        if ($row['uid'] > 0 && ($row['pid'] > 0 || in_array($table, $this->tableNamesAllowedOnRootLevel, true))) {
+            if ($GLOBALS['TCA'][$table] && $GLOBALS['TCA'][$table]['ctrl']['languageField'] && $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']) {
+                if (!$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable']) {
+                    // Will not be able to work with other tables (Just didn't implement it yet;
+                    // Requires a scan over all tables [ctrl] part for first FIND the table that
+                    // carries localization information for this table (which could even be more
+                    // than a single table) and then use that. Could be implemented, but obviously
+                    // takes a little more....) Will try to overlay a record only if the
+                    // sys_language_content value is larger than zero.
+                    if ($sys_language_content > 0) {
+                        // Must be default language or [All], otherwise no overlaying:
+                        if ($row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] <= 0) {
+                            // Select overlay record:
+                            $res = $this->getDatabaseConnection()->exec_SELECTquery('*', $table, 'pid=' . (int)$row['pid'] . ' AND ' . $GLOBALS['TCA'][$table]['ctrl']['languageField'] . '=' . (int)$sys_language_content . ' AND ' . $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] . '=' . (int)$row['uid'] . $this->enableFields($table), '', '', '1');
+                            $olrow = $this->getDatabaseConnection()->sql_fetch_assoc($res);
+                            $this->getDatabaseConnection()->sql_free_result($res);
+                            $this->versionOL($table, $olrow);
+                            // Merge record content by traversing all fields:
+                            if (is_array($olrow)) {
+                                if (isset($olrow['_ORIG_uid'])) {
+                                    $row['_ORIG_uid'] = $olrow['_ORIG_uid'];
+                                }
+                                if (isset($olrow['_ORIG_pid'])) {
+                                    $row['_ORIG_pid'] = $olrow['_ORIG_pid'];
+                                }
+                                foreach ($row as $fN => $fV) {
+                                    if ($fN !== 'uid' && $fN !== 'pid' && isset($olrow[$fN])) {
+                                        if ($this->shouldFieldBeOverlaid($table, $fN, $olrow[$fN])) {
+                                            $row[$fN] = $olrow[$fN];
+                                        }
+                                    } elseif ($fN === 'uid') {
+                                        $row['_LOCALIZED_UID'] = $olrow['uid'];
+                                    }
+                                }
+                            } elseif ($OLmode === 'hideNonTranslated' && (int)$row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] === 0) {
+                                // Unset, if non-translated records should be hidden. ONLY done if the source
+                                // record really is default language and not [All] in which case it is allowed.
+                                $row = null;
+                            }
+                        } elseif ($sys_language_content != $row[$GLOBALS['TCA'][$table]['ctrl']['languageField']]) {
+                            $row = null;
+                        }
+                    } else {
+                        // When default language is displayed, we never want to return a record carrying
+                        // another language!
+                        if ($row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] > 0) {
+                            $row = null;
+                        }
+                    }
+                }
+            }
+        }
+        if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'])) {
+            foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getRecordOverlay'] as $classRef) {
+                $hookObject = GeneralUtility::getUserObj($classRef);
+                if (!$hookObject instanceof PageRepositoryGetRecordOverlayHookInterface) {
+                    throw new \UnexpectedValueException('$hookObject must implement interface ' . PageRepositoryGetRecordOverlayHookInterface::class, 1269881659);
+                }
+                $hookObject->getRecordOverlay_postProcess($table, $row, $sys_language_content, $OLmode, $this);
+            }
+        }
+
+        return $row;
+    }
+
+    /**
+     * Creates language-overlay for records in general (where translation is found
+     * in records from the same table)
+     *
+     * @param string $table Table name
+     * @param array $row Record to overlay. Must contain uid, pid and $table]['ctrl']['languageField']
+     * @param int $sys_language_content Pointer to the sys_language uid for content on the site.
+     * @param string $OLmode Overlay mode. If "hideNonTranslated" then records without translation will not be returned  un-translated but unset (and return value is FALSE)
+     * @throws \UnexpectedValueException
+     * @return mixed Returns the input record, possibly overlaid with a translation.  But if $OLmode is "hideNonTranslated" then it will return FALSE if no translation is found.
+     * @deprecated
+     */
+    public function getRecordOverlay($table, $row, $sys_language_content, $OLmode = '') {
+        GeneralUtility::logDeprecatedFunction();
+        return $this->getRecordOverlayWithoutFallback($table, $row, $sys_language_content, $OLmode);
+    }
+
     /************************************************
      *
      * Page related: Menu, Domain record, Root line
diff --git a/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/AbstractMenuContentObjectTest.php b/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/AbstractMenuContentObjectTest.php
index 9cf1321c45..ee794474ff 100644
--- a/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/AbstractMenuContentObjectTest.php
+++ b/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/AbstractMenuContentObjectTest.php
@@ -132,7 +132,7 @@ class AbstractMenuContentObjectTest extends \TYPO3\TestingFramework\Core\Unit\Un
         $GLOBALS['TSFE']->sys_language_contentOL = 1;
         $this->subject->sys_page->expects($this->once())->method('getPage')->will($this->returnValue(['_PAGES_OVERLAY_LANGUAGE' => 1]));
         $this->subject->parent_cObj->expects($this->once())->method('exec_getQuery')->willReturn($statementProphet->reveal());
-        $this->subject->sys_page->expects($this->once())->method('getRecordOverlay')->will($this->returnValue(['uid' => 0, 'header' => 'OVERLAID']));
+        $this->subject->sys_page->expects($this->once())->method('getRecordOverlayWithFallback')->will($this->returnValue(['uid' => 0, 'header' => 'OVERLAID']));
         $result = $this->subject->_call('sectionIndex', 'field');
         $this->assertEquals($result[0]['title'], 'OVERLAID');
     }
