diff --git a/src/components/autocomplete/AutoComplete.js b/src/components/autocomplete/AutoComplete.js
index 07627c03ee..876f5fd707 100644
--- a/src/components/autocomplete/AutoComplete.js
+++ b/src/components/autocomplete/AutoComplete.js
@@ -28,6 +28,7 @@ export class AutoComplete extends Component {
         optionGroupTemplate: null,
         forceSelection: false,
         autoHighlight: false,
+        virtualScrollerOptions: null,
         scrollHeight: '200px',
         dropdown: false,
         dropdownMode: 'blank',
@@ -86,6 +87,7 @@ export class AutoComplete extends Component {
         optionGroupTemplate: PropTypes.any,
         forceSelection: PropTypes.bool,
         autoHighlight: PropTypes.bool,
+        virtualScrollerOptions: PropTypes.object,
         scrollHeight: PropTypes.string,
         dropdown: PropTypes.bool,
         dropdownMode: PropTypes.string,
@@ -160,6 +162,7 @@ export class AutoComplete extends Component {
         this.onPanelClick = this.onPanelClick.bind(this);
 
         this.overlayRef = createRef();
+        this.virtualScrollerRef = createRef();
         this.inputRef = createRef(this.props.inputRef);
     }
 
@@ -377,7 +380,7 @@ export class AutoComplete extends Component {
                         }
                     }
                     else {
-                        highlightItem = this.overlayRef.current.firstChild.firstChild;
+                        highlightItem = DomHandler.findSingle(this.overlayRef.current, 'li');
                         if (DomHandler.hasClass(highlightItem, 'p-autocomplete-item-group')) {
                             highlightItem = this.findNextItem(highlightItem);
                         }
@@ -834,13 +837,9 @@ export class AutoComplete extends Component {
                 {input}
                 {loader}
                 {dropdown}
-                <AutoCompletePanel ref={this.overlayRef} suggestions={this.props.suggestions} field={this.props.field} listId={this.state.id + '_list'}
-                    appendTo={this.props.appendTo} scrollHeight={this.props.scrollHeight} itemTemplate={this.props.itemTemplate} onItemClick={this.selectItem} ariaSelected={this.ariaSelected}
-                    panelStyle={this.props.panelStyle} panelClassName={this.props.panelClassName} onClick={this.onPanelClick}
-                    optionGroupLabel={this.props.optionGroupLabel} optionGroupChildren={this.props.optionGroupChildren} optionGroupTemplate={this.props.optionGroupTemplate}
-                    getOptionGroupLabel={this.getOptionGroupLabel} getOptionGroupChildren={this.getOptionGroupChildren}
-                    in={this.state.overlayVisible} onEnter={this.onOverlayEnter} onEntering={this.onOverlayEntering} onEntered={this.onOverlayEntered} onExit={this.onOverlayExit} onExited={this.onOverlayExited}
-                    transitionOptions={this.props.transitionOptions} />
+                <AutoCompletePanel ref={this.overlayRef} virtualScrollerRef={this.virtualScrollerRef} {...this.props} listId={this.state.id + '_list'} onItemClick={this.selectItem} ariaSelected={this.ariaSelected}
+                    onClick={this.onPanelClick} getOptionGroupLabel={this.getOptionGroupLabel} getOptionGroupChildren={this.getOptionGroupChildren}
+                    in={this.state.overlayVisible} onEnter={this.onOverlayEnter} onEntering={this.onOverlayEntering} onEntered={this.onOverlayEntered} onExit={this.onOverlayExit} onExited={this.onOverlayExited} />
             </span>
         );
     }
diff --git a/src/components/autocomplete/AutoCompletePanel.js b/src/components/autocomplete/AutoCompletePanel.js
index 021d6685cf..a9e7940a55 100644
--- a/src/components/autocomplete/AutoCompletePanel.js
+++ b/src/components/autocomplete/AutoCompletePanel.js
@@ -1,53 +1,13 @@
 import React, { Component } from 'react';
-import PropTypes from 'prop-types';
 import ObjectUtils from '../utils/ObjectUtils';
 import { Ripple } from '../ripple/Ripple';
 import { classNames } from '../utils/ClassNames';
 import { CSSTransition } from '../transition/CSSTransition';
 import { Portal } from '../portal/Portal';
+import { VirtualScroller } from '../virtualscroller/VirtualScroller';
 
 class AutoCompletePanelComponent extends Component {
 
-    static defaultProps = {
-        suggestions: null,
-        field: null,
-        appendTo: null,
-        optionGroupLabel: null,
-        optionGroupChildren: null,
-        optionGroupTemplate: null,
-        itemTemplate: null,
-        onItemClick: null,
-        scrollHeight: '200px',
-        listId: null,
-        ariaSelected: null,
-        panelClassName: null,
-        panelStyle: null,
-        forwardRef: null,
-        onClick: null,
-        getOptionGroupLabel: null,
-        getOptionGroupChildren: null
-    }
-
-    static propTypes = {
-        suggestions: PropTypes.array,
-        field: PropTypes.string,
-        appendTo: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
-        optionGroupLabel: PropTypes.string,
-        optionGroupChildren: PropTypes.string,
-        optionGroupTemplate: PropTypes.any,
-        itemTemplate: PropTypes.any,
-        onItemClick: PropTypes.func,
-        scrollHeight: PropTypes.string,
-        listId: PropTypes.any,
-        ariaSelected: PropTypes.any,
-        panelClassName: PropTypes.string,
-        panelStyle: PropTypes.object,
-        forwardRef: PropTypes.any,
-        onClick: PropTypes.func,
-        getOptionGroupLabel: PropTypes.func,
-        getOptionGroupChildren: PropTypes.func
-    };
-
     getOptionGroupRenderKey(optionGroup) {
         return ObjectUtils.resolveFieldData(optionGroup, this.props.optionGroupLabel);
     }
@@ -68,53 +28,81 @@ class AutoCompletePanelComponent extends Component {
         )
     }
 
+    renderItem(suggestion, index) {
+        if (this.props.optionGroupLabel) {
+            const groupContent = this.props.optionGroupTemplate ? ObjectUtils.getJSXElement(this.props.optionGroupTemplate, suggestion, index) : this.props.getOptionGroupLabel(suggestion);
+            const groupChildrenContent = this.renderGroupChildren(suggestion, index);
+            const key = index + '_' + this.getOptionGroupRenderKey(suggestion);
+
+            return (
+                <React.Fragment key={key}>
+                    <li className="p-autocomplete-item-group">
+                        {groupContent}
+                    </li>
+                    {groupChildrenContent}
+                </React.Fragment>
+            )
+        }
+        else {
+            let itemContent = this.props.itemTemplate ? ObjectUtils.getJSXElement(this.props.itemTemplate, suggestion, index) : this.props.field ? ObjectUtils.resolveFieldData(suggestion, this.props.field) : suggestion;
+
+            return (
+                <li key={index + '_item'} role="option" aria-selected={this.props.ariaSelected === suggestion} className="p-autocomplete-item" onClick={(e) => this.props.onItemClick(e, suggestion)}>
+                    {itemContent}
+                    <Ripple />
+                </li>
+            );
+        }
+    }
+
     renderItems() {
         if (this.props.suggestions) {
-            if (this.props.optionGroupLabel) {
-                return this.props.suggestions.map((suggestion, i) => {
-                    const groupContent = this.props.optionGroupTemplate ? ObjectUtils.getJSXElement(this.props.optionGroupTemplate, suggestion, i) : this.props.getOptionGroupLabel(suggestion);
-                    const groupChildrenContent = this.renderGroupChildren(suggestion, i);
-                    const key = i + '_' + this.getOptionGroupRenderKey(suggestion);
+            return this.props.suggestions.map((suggestion, index) => this.renderItem(suggestion, index));
+        }
 
-                    return (
-                        <React.Fragment key={key}>
-                            <li className="p-autocomplete-item-group">
-                                {groupContent}
-                            </li>
-                            {groupChildrenContent}
-                        </React.Fragment>
-                    )
-                });
-            }
-            else {
-                return this.props.suggestions.map((suggestion, index) => {
-                    let itemContent = this.props.itemTemplate ? ObjectUtils.getJSXElement(this.props.itemTemplate, suggestion, index) : this.props.field ? ObjectUtils.resolveFieldData(suggestion, this.props.field) : suggestion;
+        return null;
+    }
+
+    renderContent() {
+        if (this.props.virtualScrollerOptions) {
+            const virtualScrollerProps = { ...this.props.virtualScrollerOptions, ...{
+                style: {...this.props.virtualScrollerOptions.style, ...{ height: this.props.scrollHeight || 'auto' }},
+                items: this.props.suggestions,
+                itemTemplate: (item, options) => item && this.renderItem(item, options.index),
+                contentTemplate: (options) => {
+                    const className = classNames('p-autocomplete-items', options.className);
 
                     return (
-                        <li key={index + '_item'} role="option" aria-selected={this.props.ariaSelected === suggestion} className="p-autocomplete-item" onClick={(e) => this.props.onItemClick(e, suggestion)}>
-                            {itemContent}
-                            <Ripple />
-                        </li>
+                        <ul ref={options.ref} className={className} role="listbox" id={this.props.listId}>
+                            {options.children}
+                        </ul>
                     );
-                });
-            }
+                }
+            }};
+
+            return <VirtualScroller ref={this.props.virtualScrollerRef} {...virtualScrollerProps} />;
         }
+        else {
+            const items = this.renderItems();
 
-        return null;
+            return (
+                <ul className="p-autocomplete-items" role="listbox" id={this.props.listId}>
+                    {items}
+                </ul>
+            );
+        }
     }
 
     renderElement() {
         const panelClassName = classNames('p-autocomplete-panel p-component', this.props.panelClassName);
         const panelStyle = { maxHeight: this.props.scrollHeight, ...this.props.panelStyle };
-        let items = this.renderItems();
+        const content = this.renderContent();
 
         return (
             <CSSTransition nodeRef={this.props.forwardRef} classNames="p-connected-overlay" in={this.props.in} timeout={{ enter: 120, exit: 100 }} options={this.props.transitionOptions}
                 unmountOnExit onEnter={this.props.onEnter} onEntering={this.props.onEntering} onEntered={this.props.onEntered} onExit={this.props.onExit} onExited={this.props.onExited}>
                 <div ref={this.props.forwardRef} className={panelClassName} style={panelStyle} onClick={this.props.onClick}>
-                    <ul className="p-autocomplete-items" role="listbox" id={this.props.listId} style={{ maxHeight: this.props.scrollHeight || 'auto' }}>
-                        {items}
-                    </ul>
+                    {content}
                 </div>
             </CSSTransition>
         );